@coopdigital/react 0.44.0 → 0.45.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.
Files changed (66) hide show
  1. package/dist/components/Checkbox/Checkbox.d.ts +4 -24
  2. package/dist/components/Checkbox/Checkbox.js +7 -14
  3. package/dist/components/Checkbox/index.d.ts +1 -2
  4. package/dist/components/Field/Field.d.ts +44 -5
  5. package/dist/components/Field/Field.js +68 -5
  6. package/dist/components/FieldMarkers/Error.d.ts +9 -0
  7. package/dist/components/{FieldError/FieldError.js → FieldMarkers/Error.js} +2 -2
  8. package/dist/components/FieldMarkers/Hint.d.ts +9 -0
  9. package/dist/components/{FieldHint/FieldHint.js → FieldMarkers/Hint.js} +2 -2
  10. package/dist/components/FieldMarkers/Label.d.ts +11 -0
  11. package/dist/components/FieldMarkers/Label.js +8 -0
  12. package/dist/components/FieldMarkers/Legend.d.ts +11 -0
  13. package/dist/components/FieldMarkers/Legend.js +13 -0
  14. package/dist/components/Fieldset/Fieldset.d.ts +54 -0
  15. package/dist/components/Fieldset/Fieldset.js +44 -0
  16. package/dist/components/Fieldset/index.d.ts +4 -0
  17. package/dist/components/RadioButton/RadioButton.d.ts +4 -22
  18. package/dist/components/RadioButton/RadioButton.js +5 -9
  19. package/dist/components/RadioButton/index.d.ts +1 -2
  20. package/dist/components/SearchBox/SearchBox.js +3 -3
  21. package/dist/components/TextInput/TextInput.d.ts +4 -18
  22. package/dist/components/TextInput/TextInput.js +7 -11
  23. package/dist/components/Textarea/Textarea.d.ts +4 -18
  24. package/dist/components/Textarea/Textarea.js +8 -9
  25. package/dist/hooks/useId.d.ts +2 -0
  26. package/dist/hooks/useId.js +8 -0
  27. package/dist/index.d.ts +1 -3
  28. package/dist/index.js +2 -6
  29. package/dist/utils/slots.d.ts +3 -1
  30. package/dist/utils/slots.js +8 -2
  31. package/package.json +10 -10
  32. package/src/components/Checkbox/Checkbox.tsx +8 -64
  33. package/src/components/Checkbox/index.ts +1 -2
  34. package/src/components/Field/Field.tsx +144 -8
  35. package/src/components/{FieldError/FieldError.tsx → FieldMarkers/Error.tsx} +4 -4
  36. package/src/components/{FieldHint/FieldHint.tsx → FieldMarkers/Hint.tsx} +5 -9
  37. package/src/components/FieldMarkers/Label.tsx +21 -0
  38. package/src/components/FieldMarkers/Legend.tsx +28 -0
  39. package/src/components/Fieldset/Fieldset.tsx +98 -0
  40. package/src/components/Fieldset/index.ts +5 -0
  41. package/src/components/RadioButton/RadioButton.tsx +6 -55
  42. package/src/components/RadioButton/index.ts +1 -2
  43. package/src/components/SearchBox/SearchBox.tsx +4 -2
  44. package/src/components/TextInput/TextInput.tsx +12 -45
  45. package/src/components/Textarea/Textarea.tsx +12 -40
  46. package/src/hooks/useId.ts +9 -0
  47. package/src/index.ts +1 -3
  48. package/src/utils/slots.ts +10 -2
  49. package/dist/components/Checkbox/CheckboxGroup.d.ts +0 -32
  50. package/dist/components/Checkbox/CheckboxGroup.js +0 -21
  51. package/dist/components/FieldError/FieldError.d.ts +0 -9
  52. package/dist/components/FieldError/index.d.ts +0 -4
  53. package/dist/components/FieldHint/FieldHint.d.ts +0 -9
  54. package/dist/components/FieldHint/index.d.ts +0 -4
  55. package/dist/components/FieldLabel/FieldLabel.d.ts +0 -13
  56. package/dist/components/FieldLabel/FieldLabel.js +0 -13
  57. package/dist/components/FieldLabel/index.d.ts +0 -4
  58. package/dist/components/RadioButton/RadioButtonGroup.d.ts +0 -32
  59. package/dist/components/RadioButton/RadioButtonGroup.js +0 -21
  60. package/dist/components/Tag/index.js +0 -5
  61. package/src/components/Checkbox/CheckboxGroup.tsx +0 -73
  62. package/src/components/FieldError/index.ts +0 -5
  63. package/src/components/FieldHint/index.ts +0 -5
  64. package/src/components/FieldLabel/FieldLabel.tsx +0 -31
  65. package/src/components/FieldLabel/index.ts +0 -5
  66. package/src/components/RadioButton/RadioButtonGroup.tsx +0 -73
@@ -0,0 +1,98 @@
1
+ import clsx from "clsx"
2
+ import { type FieldsetHTMLAttributes, type JSX } from "react"
3
+
4
+ import { StandardSizes } from "../../../src/types"
5
+ import { Error as BaseError, type ErrorProps } from "../FieldMarkers/Error"
6
+ import { Hint as BaseHint, type HintProps } from "../FieldMarkers/Hint"
7
+ import { Legend as BaseLegend, type LegendProps } from "../FieldMarkers/Legend"
8
+
9
+ export interface FieldsetProps extends FieldsetHTMLAttributes<HTMLFieldSetElement> {
10
+ /** Form elements inside the Fieldset.
11
+ *
12
+ * Usually this will be a combination of `Fieldset.Legend` and `Fieldset.Fields`. */
13
+ children: React.ReactNode
14
+ /** **(Optional)** Specify additional CSS classes to be applied to the component. */
15
+ className?: string
16
+ /** **(Optional)** Specify whether the Fieldset, and all of its descendents, should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
17
+ disabled?: boolean
18
+ /** **(Optional)** Specify the Fieldset error state. Use this to apply visual styling to the field control. */
19
+ error?: boolean
20
+ /** **(Optional)** Specify whether the Fieldset should show the left-hand error bar if it is in an error state. */
21
+ hideErrorBar?: boolean
22
+ /** **(Optional)** Specify the size of the Fieldset and all its descendents. */
23
+ size?: StandardSizes
24
+ }
25
+ const Root = ({
26
+ children,
27
+ className,
28
+ disabled,
29
+ error = false,
30
+ hideErrorBar = false,
31
+ size = "md",
32
+ ...props
33
+ }: FieldsetProps): JSX.Element => {
34
+ const componentProps = {
35
+ "aria-disabled": disabled,
36
+ className: clsx("coop-fieldset", className),
37
+ "data-error": error || undefined,
38
+ //"data-variant": variant !== "default" ? variant : undefined,
39
+ "data-hide-error": hideErrorBar || undefined,
40
+ // "data-orientation": orientation !== "vertical" ? orientation : undefined,
41
+ "data-size": size.length && size !== "md" ? size : undefined,
42
+ disabled,
43
+ ...props,
44
+ }
45
+
46
+ return <fieldset {...componentProps}>{children}</fieldset>
47
+ }
48
+
49
+ interface FieldsetFieldsProps {
50
+ /** **(Optional)** Specify whether all descendent Fields should render inside a box. */
51
+ boxed?: boolean
52
+ /** **(Optional)** Form elements inside the Fieldset.Fields container. */
53
+ children?: string | React.ReactNode
54
+ /** **(Optional)** Specify additional CSS classes to be applied to the component. */
55
+ className?: string
56
+ /** **(Optional)** Specify the CheckboxGroup orientation. */
57
+ orientation?: "horizontal" | "vertical"
58
+ }
59
+
60
+ export const FieldsetFields = ({
61
+ boxed = false,
62
+ children,
63
+ className,
64
+ orientation = "vertical",
65
+ ...props
66
+ }: FieldsetFieldsProps): JSX.Element => {
67
+ const componentProps = {
68
+ className: clsx("coop-fieldset-fields", className),
69
+ "data-boxed": boxed || undefined,
70
+ "data-orientation": orientation !== "vertical" ? orientation : undefined,
71
+ ...props,
72
+ }
73
+
74
+ return <div {...componentProps}>{children}</div>
75
+ }
76
+
77
+ FieldsetFields.displayName = "Fieldset.Fields"
78
+
79
+ const FieldsetLegend = (props: LegendProps) => <BaseLegend {...props} />
80
+
81
+ FieldsetLegend.displayName = "Fieldset.Legend"
82
+
83
+ const FieldsetHint = (props: HintProps) => <BaseHint {...props} />
84
+
85
+ FieldsetHint.displayName = "Fieldset.Hint"
86
+
87
+ const FieldsetError = (props: ErrorProps) => <BaseError {...props} />
88
+
89
+ FieldsetError.displayName = "Fieldset.Error"
90
+
91
+ export const Fieldset = Object.assign(Root, {
92
+ Error: FieldsetError,
93
+ Fields: FieldsetFields,
94
+ Hint: FieldsetHint,
95
+ Legend: FieldsetLegend,
96
+ })
97
+
98
+ export default Fieldset
@@ -0,0 +1,5 @@
1
+ import Fieldset from "./Fieldset"
2
+
3
+ export default Fieldset
4
+ export { Fieldset }
5
+ export * from "./Fieldset"
@@ -1,11 +1,6 @@
1
1
  import clsx from "clsx"
2
2
  import { type InputHTMLAttributes, type JSX, useId } from "react"
3
- import { FormFieldError, StandardSizes } from "src/types"
4
-
5
- import { FieldError } from "../FieldError"
6
- import { FieldHint } from "../FieldHint"
7
- import { FieldLabel } from "../FieldLabel"
8
- import Tag from "../Tag"
3
+ import { StandardSizes } from "src/types"
9
4
 
10
5
  export interface RadioButtonProps
11
6
  extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> {
@@ -13,46 +8,23 @@ export interface RadioButtonProps
13
8
  className?: string
14
9
  /** **(Optional)** Specify whether the RadioButton should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
15
10
  disabled?: boolean
16
- /** **(Optional)** Specify the RadioButton error state.
17
- *
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.
19
- */
20
- error?: FormFieldError
21
- /** **(Optional)** Specify the RadioButton hint.
22
- *
23
- * This text is rendered under the label to provide further guidance for users.
24
- */
25
- hint?: string
11
+ /** **(Optional)** Specify the RadioButton error state. */
12
+ error?: boolean
26
13
  /** **(Optional)** Specify the RadioButton id. Will be auto-generated if not set. */
27
14
  id?: string
28
- /** **(Optional)** Specify the RadioButton label.
29
- *
30
- * This property is optional in case you need to render your own label, but all form elements *must* provide a label. */
31
- label: string
32
- /** **(Optional)** Specify whether the label should be visible to humans or screen readers. */
33
- labelVisible?: boolean
34
15
  /** Specify the RadioButton name. */
35
16
  name: string
36
17
  /** **(Optional)** Specify the RadioButton size. */
37
18
  size?: StandardSizes
38
- /** **(Optional)** Specify the RadioButton tag text. */
39
- tag?: string
40
- /** **(Optional)** Specify the RadioButton tag className. */
41
- tagClassName?: string
42
19
  }
43
20
 
44
21
  export const RadioButton = ({
45
22
  className,
46
23
  disabled,
47
24
  error = false,
48
- hint,
49
25
  id,
50
- label,
51
- labelVisible = true,
52
26
  name,
53
27
  size = "md",
54
- tag,
55
- tagClassName,
56
28
  ...props
57
29
  }: RadioButtonProps): JSX.Element => {
58
30
  const internalId = useId()
@@ -61,7 +33,7 @@ export const RadioButton = ({
61
33
 
62
34
  const componentProps = {
63
35
  className: clsx("coop-radio-button", className),
64
- "data-error": error ? "" : undefined,
36
+ "data-error": error || undefined,
65
37
  "data-size": size.length && size !== "md" ? size : undefined,
66
38
  disabled,
67
39
  id,
@@ -69,29 +41,8 @@ export const RadioButton = ({
69
41
  type: "radio",
70
42
  ...props,
71
43
  }
72
- const formItemProps = { "aria-disabled": disabled ? true : undefined }
73
- return (
74
- <div className="coop-form-item" {...formItemProps}>
75
- <div className="coop-radio-button-wrapper">
76
- <div className="coop-radio-button-input-wrapper">
77
- <input {...componentProps} />
78
-
79
- {label && (
80
- <FieldLabel htmlFor={id} isVisible={labelVisible}>
81
- <span>{label}</span>{" "}
82
- {tag && (
83
- <Tag className={tagClassName} size="sm">
84
- {tag}
85
- </Tag>
86
- )}
87
- </FieldLabel>
88
- )}
89
- </div>
90
- {hint && <FieldHint>{hint}</FieldHint>}
91
- </div>
92
- {typeof error === "object" && error?.message && <FieldError>{error.message}</FieldError>}
93
- </div>
94
- )
44
+ //const formItemProps = { "aria-disabled": disabled ? true : undefined }
45
+ return <input {...componentProps} />
95
46
  }
96
47
 
97
48
  export default RadioButton
@@ -1,6 +1,5 @@
1
1
  import RadioButton from "./RadioButton"
2
- import RadioButtonGroup from "./RadioButtonGroup"
3
2
 
4
3
  export default RadioButton
5
- export { RadioButton, RadioButtonGroup }
4
+ export { RadioButton }
6
5
  export * from "./RadioButton"
@@ -7,7 +7,7 @@ import React, { useCallback, useId, useState } from "react"
7
7
 
8
8
  import { StandardSizes } from "../../../src/types"
9
9
  import { Button, type ButtonProps } from "../Button"
10
- import { FieldLabel } from "../FieldLabel"
10
+ import { Label as FieldLabel } from "../FieldMarkers/Label"
11
11
  import { SearchIcon } from "../Icon"
12
12
  import TextInput, { TextInputProps } from "../TextInput"
13
13
 
@@ -57,6 +57,7 @@ export const SearchBox = ({
57
57
  autoComplete = "off",
58
58
  button = defaultButtonProps,
59
59
  className,
60
+
60
61
  id,
61
62
  label,
62
63
  labelVisible = false,
@@ -92,7 +93,7 @@ export const SearchBox = ({
92
93
  const formProps = {
93
94
  action: action ?? undefined,
94
95
  className: clsx("coop-search-box", className),
95
- //"data-size": size && size !== "md" ? size : undefined,
96
+ "data-size": size && size !== "md" ? size : undefined,
96
97
  "data-variant": variant.length && variant !== "green" ? variant : undefined,
97
98
  onSubmit: onSubmit ? handleSubmit : undefined,
98
99
  }
@@ -126,6 +127,7 @@ export const SearchBox = ({
126
127
  )}
127
128
  <div className="coop-search-box--inner">
128
129
  <TextInput {...inputProps} />
130
+
129
131
  <Button {...buttonProps}>{button.label}</Button>
130
132
  </div>
131
133
  </form>
@@ -1,12 +1,9 @@
1
1
  import type { InputHTMLAttributes, JSX } from "react"
2
2
 
3
3
  import clsx from "clsx"
4
- import { useId } from "react"
5
4
 
6
- import { FormFieldError, StandardSizes } from "../../../src/types"
7
- import { FieldError } from "../FieldError"
8
- import { FieldHint } from "../FieldHint"
9
- import { FieldLabel } from "../FieldLabel"
5
+ import { StandardSizes } from "../../../src/types"
6
+ import { useId } from "../../hooks/useId"
10
7
 
11
8
  export interface TextInputProps
12
9
  extends Omit<InputHTMLAttributes<HTMLInputElement>, "prefix" | "size" | "type"> {
@@ -14,24 +11,10 @@ export interface TextInputProps
14
11
  className?: string
15
12
  /** **(Optional)** Specify whether the TextInput should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
16
13
  disabled?: boolean
17
- /** **(Optional)** Specify the TextInput error state.
18
- *
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.
20
- */
21
- error?: FormFieldError
22
- /** **(Optional)** Specify the TextInput hint.
23
- *
24
- * This text is rendered under the label to provide further guidance for users.
25
- */
26
- hint?: string
14
+ /** **(Optional)** Specify the TextInput error state. */
15
+ error?: boolean
27
16
  /** **(Optional)** Specify the TextInput id. Will be auto-generated if not set. */
28
17
  id?: string
29
- /** **(Optional)** Specify the TextInput label.
30
- *
31
- * This property is optional in case you need to render your own label, but all form elements *must* provide a label. */
32
- label?: string
33
- /** **(Optional)** Specify whether the label should be visible to humans or screen readers. */
34
- labelVisible?: boolean
35
18
  /** Specify the TextInput name. */
36
19
  name: string
37
20
  /** **(Optional)** Specify the TextInput placeholder text. Do not use in place of a form label. */
@@ -51,10 +34,7 @@ export const TextInput = ({
51
34
  className,
52
35
  disabled,
53
36
  error = false,
54
- hint,
55
37
  id,
56
- label,
57
- labelVisible = true,
58
38
  name,
59
39
  placeholder,
60
40
  prefix,
@@ -63,39 +43,26 @@ export const TextInput = ({
63
43
  type = "text",
64
44
  ...props
65
45
  }: TextInputProps): JSX.Element => {
66
- const internalId = useId()
67
-
68
- id = id ?? internalId
46
+ const uid = useId(id)
69
47
 
70
48
  const componentProps = {
71
49
  "aria-placeholder": placeholder ?? ariaPlaceholder ?? undefined,
72
50
  className: clsx("coop-text-input", className),
73
- "data-error": error ? "" : undefined,
51
+ "data-error": error || undefined,
74
52
  "data-size": size.length && size !== "md" ? size : undefined,
75
53
  disabled,
76
- id,
54
+ id: uid,
77
55
  name,
78
56
  placeholder,
79
57
  type,
80
58
  ...props,
81
59
  }
82
- const formItemProps = { "aria-disabled": disabled ? true : undefined }
60
+ //const formItemProps = { "aria-disabled": disabled ? true : undefined }
83
61
  return (
84
- <div className="coop-form-item" {...formItemProps}>
85
- {label && (
86
- <FieldLabel htmlFor={id} isVisible={labelVisible}>
87
- {label}
88
- </FieldLabel>
89
- )}
90
-
91
- {hint && <FieldHint>{hint}</FieldHint>}
92
-
93
- {typeof error === "object" && error?.message && <FieldError>{error.message}</FieldError>}
94
- <div className="coop-text-input-wrapper">
95
- {prefix && <span className="coop-text-input--prefix">{prefix}</span>}
96
- <input {...componentProps} />
97
- {suffix && <span className="coop-text-input--suffix">{suffix}</span>}
98
- </div>
62
+ <div className="coop-text-input-wrapper">
63
+ {prefix && <span className="coop-text-input--prefix">{prefix}</span>}
64
+ <input {...componentProps} />
65
+ {suffix && <span className="coop-text-input--suffix">{suffix}</span>}
99
66
  </div>
100
67
  )
101
68
  }
@@ -1,13 +1,11 @@
1
1
  import type { ChangeEvent, JSX, TextareaHTMLAttributes } from "react"
2
2
 
3
3
  import clsx from "clsx"
4
- import { useId, useState } from "react"
4
+ import { useState } from "react"
5
5
 
6
6
  import { useDebounce } from "../../hooks/useDebounce"
7
- import { FormFieldError, StandardSizes } from "../../types"
8
- import { FieldError } from "../FieldError"
9
- import { FieldHint } from "../FieldHint"
10
- import { FieldLabel } from "../FieldLabel"
7
+ import { useId } from "../../hooks/useId"
8
+ import { StandardSizes } from "../../types"
11
9
 
12
10
  const DEBOUNCE_DELAY = 750
13
11
 
@@ -31,24 +29,10 @@ export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElemen
31
29
  cutoff?: boolean
32
30
  /** **(Optional)** Specify whether the Textarea should be disabled. Refer to Experience Library guidance on disabled form controls and accessibility. */
33
31
  disabled?: boolean
34
- /** **(Optional)** Specify the Textarea error state.
35
- *
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.
37
- */
38
- error?: FormFieldError
39
- /** **(Optional)** Specify the Textarea hint.
40
- *
41
- * This text is rendered under the label to provide further guidance for users.
42
- */
43
- hint?: string
32
+ /** **(Optional)** Specify the Textarea error state */
33
+ error?: boolean
44
34
  /** **(Optional)** Specify the Textarea id. Will be auto-generated if not set. */
45
35
  id?: string
46
- /** **(Optional)** Specify the Textarea label.
47
- *
48
- * This property is optional in case you need to render your own label, but all form elements *must* provide a label. */
49
- label?: string
50
- /** **(Optional)** Specify whether the label should be visible to humans or screen readers. */
51
- labelVisible?: boolean
52
36
  /** **(Optional)** Specify the Textarea maxLength. This is the maximum number of characters users can enter. */
53
37
  maxLength?: number
54
38
  /** Specify the Textarea name. */
@@ -69,10 +53,7 @@ export const Textarea = ({
69
53
  cutoff = false,
70
54
  disabled = false,
71
55
  error = false,
72
- hint,
73
56
  id,
74
- label,
75
- labelVisible = true,
76
57
  maxLength,
77
58
  name,
78
59
  onChange: userOnChange = undefined,
@@ -89,7 +70,7 @@ export const Textarea = ({
89
70
  "aria-placeholder": placeholder ?? ariaPlaceholder ?? undefined,
90
71
  className: clsx("coop-textarea", className),
91
72
  cols,
92
- "data-error": error ? "" : undefined,
73
+ "data-error": error ?? undefined,
93
74
  "data-size": size.length && size !== "md" ? size : undefined,
94
75
  disabled,
95
76
  id,
@@ -102,23 +83,15 @@ export const Textarea = ({
102
83
 
103
84
  const [remaining, setRemaining] = useState(maxLength)
104
85
  const debouncedRemaining = useDebounce(remaining, DEBOUNCE_DELAY)
86
+ const showCounter =
87
+ !disabled && counter && maxLength && remaining != null && debouncedRemaining != null
105
88
 
106
89
  const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
107
90
  maxLength && e.target && setRemaining(maxLength - e.target.value.length)
108
91
  }
109
- const formItemProps = { "aria-disabled": disabled ? true : undefined }
92
+ // const formItemProps = { "aria-disabled": disabled ? true : undefined }
110
93
  return (
111
- <div className="coop-form-item" {...formItemProps}>
112
- {label && (
113
- <FieldLabel htmlFor={id} isVisible={labelVisible}>
114
- {label}
115
- </FieldLabel>
116
- )}
117
-
118
- {hint && <FieldHint>{hint}</FieldHint>}
119
-
120
- {typeof error === "object" && error?.message && <FieldError>{error.message}</FieldError>}
121
-
94
+ <div className="coop-textarea-wrapper">
122
95
  <textarea
123
96
  {...componentProps}
124
97
  onChange={(e) => {
@@ -126,13 +99,12 @@ export const Textarea = ({
126
99
  handleChange(e)
127
100
  }}
128
101
  ></textarea>
129
-
130
- {!disabled && counter && maxLength && remaining != null && debouncedRemaining != null && (
102
+ {showCounter && (
131
103
  <>
132
104
  <small
133
105
  aria-hidden="true"
134
106
  className="coop-textarea-counter"
135
- {...(remaining < 0 && { "data-error": "" })}
107
+ {...(remaining < 0 && { "data-error": true })}
136
108
  >
137
109
  {charCountMessage(remaining)}
138
110
  </small>
@@ -0,0 +1,9 @@
1
+ import { useId as _useId } from "react"
2
+
3
+ export type UseId = (id?: string) => string
4
+
5
+ export const useId: UseId = (id) => {
6
+ const uniqueId = _useId()
7
+
8
+ return id ?? uniqueId
9
+ }
package/src/index.ts CHANGED
@@ -5,9 +5,7 @@ export * from "./components/Card"
5
5
  export * from "./components/Checkbox"
6
6
  export * from "./components/Expandable"
7
7
  export * from "./components/Field"
8
- export * from "./components/FieldError"
9
- export * from "./components/FieldHint"
10
- export * from "./components/FieldLabel"
8
+ export * from "./components/Fieldset"
11
9
  export * from "./components/Flourish"
12
10
  export * from "./components/Image"
13
11
  export * from "./components/Pill"
@@ -12,13 +12,21 @@ export function getSlotName(node: React.ReactNode): string | false {
12
12
  : false
13
13
  }
14
14
 
15
- export function getSlots<T>(componentSlots: Slots<T>, children: React.ReactNode): Slots<T> {
15
+ export function getSlots<T>(
16
+ componentSlots: Slots<T>,
17
+ children: React.ReactNode,
18
+ options?: { collect?: string[] }
19
+ ): Slots<T> {
16
20
  return React.Children.toArray(children).reduce(
17
21
  (slots, child: React.ReactNode) => {
18
22
  const slotName = getSlotName(child)
19
23
 
20
24
  if (child && slotName && isKey(componentSlots, slotName)) {
21
- slots[slotName] = child
25
+ if (options?.collect?.includes(slotName)) {
26
+ slots[slotName] = slots[slotName] ? [...[slots[slotName]].flat(), child] : [child]
27
+ } else {
28
+ slots[slotName] = child
29
+ }
22
30
  } else if ("Children" in slots) {
23
31
  slots.Children = slots.Children ? [...[slots.Children].flat(), child] : [child]
24
32
  }
@@ -1,32 +0,0 @@
1
- import type { FieldsetHTMLAttributes, JSX } from "react";
2
- import { FormFieldError, StandardSizes } from "../../../src/types";
3
- export interface CheckboxGroupProps extends FieldsetHTMLAttributes<HTMLFieldSetElement> {
4
- /** **(Optional)** Main content inside the component. It can be any valid JSX or string. */
5
- children?: React.ReactNode;
6
- /** **(Optional)** Specify additional CSS classes to be applied to the component. */
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;
10
- /** **(Optional)** Specify the CheckboxGroup error state.
11
- *
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.
13
- */
14
- error?: FormFieldError;
15
- /** **(Optional)** Specify the CheckboxGroup hint.
16
- *
17
- * This text is rendered under the label to provide further guidance for users.
18
- */
19
- hint?: string;
20
- /** **(Optional)** Specify the label for the CheckboxGroup. This will be rendered as a fieldset legend. */
21
- label?: string;
22
- /** **(Optional)** Specify whether the label should be visible to humans or screen readers. */
23
- labelVisible?: boolean;
24
- /** **(Optional)** Specify the CheckboxGroup orientation. */
25
- orientation?: "horizontal" | "vertical";
26
- /** **(Optional)** Specify the CheckboxGroup size. */
27
- size?: StandardSizes;
28
- /** **(Optional)** Specify the CheckboxGroup variant. */
29
- variant?: "default" | "boxed";
30
- }
31
- export declare const CheckboxGroup: ({ children, className, error, hint, label, labelVisible, orientation, size, variant, ...props }: CheckboxGroupProps) => JSX.Element;
32
- export default CheckboxGroup;
@@ -1,21 +0,0 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
2
- import clsx from 'clsx';
3
- import { FieldError } from '../FieldError/FieldError.js';
4
- import { FieldHint } from '../FieldHint/FieldHint.js';
5
-
6
- const CheckboxGroup = ({ children, className, error = false, hint, label, labelVisible = true, orientation = "vertical", size = "md", variant = "default", ...props }) => {
7
- const componentProps = {
8
- className: clsx("coop-fieldset", "coop-checkbox-group", className),
9
- "data-error": error ? "" : undefined,
10
- "data-orientation": orientation !== "vertical" ? orientation : undefined,
11
- "data-size": size.length && size !== "md" ? size : undefined,
12
- "data-variant": variant !== "default" ? variant : undefined,
13
- ...props,
14
- };
15
- const legendProps = {
16
- className: clsx("coop-field-label", !labelVisible && "sr-only"),
17
- };
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-checkbox-group-options", children: children })] }));
19
- };
20
-
21
- export { CheckboxGroup, CheckboxGroup as default };
@@ -1,9 +0,0 @@
1
- import type { HTMLAttributes, JSX, ReactNode } from "react";
2
- export interface FieldErrorProps extends HTMLAttributes<HTMLSpanElement> {
3
- /** **(Optional)** Main content inside the component. It can be any valid JSX or string. */
4
- children?: string | ReactNode;
5
- /** **(Optional)** Specify additional CSS classes to be applied to the component. */
6
- className?: string;
7
- }
8
- export declare const FieldError: ({ children, className, ...props }: FieldErrorProps) => JSX.Element;
9
- export default FieldError;
@@ -1,4 +0,0 @@
1
- import FieldError from "./FieldError";
2
- export default FieldError;
3
- export { FieldError };
4
- export * from "./FieldError";
@@ -1,9 +0,0 @@
1
- import type { HTMLAttributes, JSX, ReactNode } from "react";
2
- export interface FieldHintProps extends HTMLAttributes<HTMLParagraphElement> {
3
- /** Main content inside the component. It can be any valid JSX or string. */
4
- children: string | ReactNode;
5
- /** **(Optional)** Specify additional CSS classes to be applied to the component. */
6
- className?: string;
7
- }
8
- export declare const FieldHint: ({ children, className, ...props }: FieldHintProps) => JSX.Element | null;
9
- export default FieldHint;
@@ -1,4 +0,0 @@
1
- import FieldHint from "./FieldHint";
2
- export default FieldHint;
3
- export { FieldHint };
4
- export * from "./FieldHint";
@@ -1,13 +0,0 @@
1
- import type { JSX, LabelHTMLAttributes, ReactNode } from "react";
2
- export interface FieldLabelProps extends LabelHTMLAttributes<HTMLLabelElement> {
3
- /** **(Optional)** Main content inside the component. It can be any valid JSX or string. */
4
- children?: string | ReactNode;
5
- /** **(Optional)** Specify additional CSS classes to be applied to the component. */
6
- className?: string;
7
- /** Specify the field ID to connect FieldLabel to the field itself. */
8
- htmlFor: string;
9
- /** **(Optional)** Specify whether the FieldLabel is visible for humans or only for screen readers. */
10
- isVisible?: boolean;
11
- }
12
- export declare const FieldLabel: ({ children, className, htmlFor, isVisible, ...props }: FieldLabelProps) => JSX.Element | null;
13
- export default FieldLabel;
@@ -1,13 +0,0 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import clsx from 'clsx';
3
-
4
- const FieldLabel = ({ children, className, htmlFor, isVisible = true, ...props }) => {
5
- const componentProps = {
6
- className: clsx("coop-field-label ", isVisible ? "" : "sr-only", className),
7
- htmlFor,
8
- ...props,
9
- };
10
- return children && htmlFor ? jsx("label", { ...componentProps, children: children }) : null;
11
- };
12
-
13
- export { FieldLabel, FieldLabel as default };
@@ -1,4 +0,0 @@
1
- import FieldLabel from "./FieldLabel";
2
- export default FieldLabel;
3
- export { FieldLabel };
4
- export * from "./FieldLabel";
@@ -1,32 +0,0 @@
1
- import type { FieldsetHTMLAttributes, JSX } from "react";
2
- import { FormFieldError, StandardSizes } from "../../types";
3
- export interface RadioButtonGroupProps extends FieldsetHTMLAttributes<HTMLFieldSetElement> {
4
- /** **(Optional)** Main content inside the component. It can be any valid JSX or string. */
5
- children?: React.ReactNode;
6
- /** **(Optional)** Specify additional CSS classes to be applied to the component. */
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;
10
- /** **(Optional)** Specify the RadioButtonGroup error state.
11
- *
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.
13
- */
14
- error?: FormFieldError;
15
- /** **(Optional)** Specify the RadioButtonGroup hint.
16
- *
17
- * This text is rendered under the label to provide further guidance for users.
18
- */
19
- hint?: string;
20
- /** **(Optional)** Specify the label for the RadioButtonGroup. This will be rendered as a fieldset legend. */
21
- label?: string;
22
- /** **(Optional)** Specify whether the label should be visible to humans or screen readers. */
23
- labelVisible?: boolean;
24
- /** **(Optional)** Specify the RadioButtonGroup orientation. */
25
- orientation?: "horizontal" | "vertical";
26
- /** **(Optional)** Specify the RadioButtonGroup size. */
27
- size?: StandardSizes;
28
- /** **(Optional)** Specify the RadioButtonGroup variant. */
29
- variant?: "default" | "boxed";
30
- }
31
- export declare const RadioButtonGroup: ({ children, className, error, hint, label, labelVisible, orientation, size, variant, ...props }: RadioButtonGroupProps) => JSX.Element;
32
- export default RadioButtonGroup;