@coopdigital/react 1.4.1 → 1.5.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 (96) hide show
  1. package/dist/components/AlertBanner/AlertBanner.d.ts +12 -2
  2. package/dist/components/AlertBanner/AlertBanner.js +3 -2
  3. package/dist/components/Author/Author.d.ts +7 -1
  4. package/dist/components/Author/Author.js +1 -0
  5. package/dist/components/Button/Button.d.ts +7 -1
  6. package/dist/components/Button/Button.js +1 -0
  7. package/dist/components/Card/Card.d.ts +40 -6
  8. package/dist/components/Card/Card.js +7 -6
  9. package/dist/components/Checkbox/Checkbox.d.ts +6 -4
  10. package/dist/components/Checkbox/Checkbox.js +9 -6
  11. package/dist/components/DatePicker/DatePicker.d.ts +8 -3
  12. package/dist/components/DatePicker/DatePicker.js +11 -11
  13. package/dist/components/Expandable/Expandable.d.ts +19 -3
  14. package/dist/components/Expandable/Expandable.js +4 -3
  15. package/dist/components/Field/Field.context.d.ts +14 -0
  16. package/dist/components/Field/Field.context.js +14 -0
  17. package/dist/components/Field/Field.d.ts +26 -4
  18. package/dist/components/Field/Field.js +33 -34
  19. package/dist/components/Field/index.js +1 -0
  20. package/dist/components/FieldMarkers/Label.js +4 -0
  21. package/dist/components/Fieldset/Fieldset.d.ts +33 -5
  22. package/dist/components/Fieldset/Fieldset.js +6 -5
  23. package/dist/components/Flourish/Flourish.d.ts +7 -1
  24. package/dist/components/Flourish/Flourish.js +1 -0
  25. package/dist/components/Form/Form.d.ts +7 -1
  26. package/dist/components/Form/Form.js +1 -0
  27. package/dist/components/Image/Image.d.ts +7 -1
  28. package/dist/components/Image/Image.js +1 -0
  29. package/dist/components/Pill/Pill.d.ts +12 -2
  30. package/dist/components/Pill/Pill.js +3 -2
  31. package/dist/components/Popover/Popover.d.ts +33 -5
  32. package/dist/components/Popover/Popover.js +6 -5
  33. package/dist/components/Popover/index.js +1 -0
  34. package/dist/components/Radio/Radio.d.ts +6 -4
  35. package/dist/components/Radio/Radio.js +9 -6
  36. package/dist/components/RootSVG/RootSVG.d.ts +7 -1
  37. package/dist/components/RootSVG/RootSVG.js +1 -0
  38. package/dist/components/Searchbox/Searchbox.context.d.ts +13 -0
  39. package/dist/components/Searchbox/Searchbox.context.js +11 -0
  40. package/dist/components/Searchbox/Searchbox.d.ts +15 -11
  41. package/dist/components/Searchbox/Searchbox.js +25 -28
  42. package/dist/components/Select/Select.d.ts +18 -5
  43. package/dist/components/Select/Select.js +9 -9
  44. package/dist/components/Signpost/Signpost.d.ts +7 -1
  45. package/dist/components/Signpost/Signpost.js +1 -0
  46. package/dist/components/SkipNav/SkipNav.d.ts +7 -1
  47. package/dist/components/SkipNav/SkipNav.js +1 -0
  48. package/dist/components/Squircle/Squircle.d.ts +7 -1
  49. package/dist/components/Squircle/Squircle.js +1 -0
  50. package/dist/components/Tag/Tag.d.ts +7 -1
  51. package/dist/components/Tag/Tag.js +1 -0
  52. package/dist/components/TextInput/TextInput.d.ts +4 -3
  53. package/dist/components/TextInput/TextInput.js +6 -6
  54. package/dist/components/Textarea/Textarea.d.ts +4 -3
  55. package/dist/components/Textarea/Textarea.js +4 -6
  56. package/dist/components/ValidationSummary/ValidationSummary.d.ts +26 -4
  57. package/dist/components/ValidationSummary/ValidationSummary.js +8 -6
  58. package/dist/hooks/useSlots.d.ts +4 -2
  59. package/dist/hooks/useSlots.js +33 -7
  60. package/dist/index.js +10 -10
  61. package/dist/types/index.d.ts +14 -14
  62. package/dist/utils/index.d.ts +1 -0
  63. package/dist/utils/index.js +9 -7
  64. package/package.json +4 -3
  65. package/src/components/AlertBanner/AlertBanner.tsx +5 -2
  66. package/src/components/Author/Author.tsx +4 -1
  67. package/src/components/Button/Button.tsx +5 -1
  68. package/src/components/Card/Card.tsx +8 -6
  69. package/src/components/Checkbox/Checkbox.tsx +13 -9
  70. package/src/components/DatePicker/DatePicker.tsx +15 -15
  71. package/src/components/Expandable/Expandable.tsx +5 -8
  72. package/src/components/Field/Field.context.ts +29 -0
  73. package/src/components/Field/Field.tsx +61 -56
  74. package/src/components/FieldMarkers/Label.tsx +4 -0
  75. package/src/components/Fieldset/Fieldset.tsx +7 -5
  76. package/src/components/Flourish/Flourish.tsx +4 -1
  77. package/src/components/Form/Form.tsx +4 -1
  78. package/src/components/Image/Image.tsx +4 -1
  79. package/src/components/Pill/Pill.tsx +4 -2
  80. package/src/components/Popover/Popover.tsx +7 -5
  81. package/src/components/Radio/Radio.tsx +12 -9
  82. package/src/components/RootSVG/RootSVG.tsx +4 -1
  83. package/src/components/Searchbox/Searchbox.context.tsx +20 -0
  84. package/src/components/Searchbox/Searchbox.tsx +55 -44
  85. package/src/components/Select/Select.tsx +11 -11
  86. package/src/components/Signpost/Signpost.tsx +4 -1
  87. package/src/components/SkipNav/SkipNav.tsx +4 -1
  88. package/src/components/Squircle/Squircle.tsx +4 -1
  89. package/src/components/Tag/Tag.tsx +4 -1
  90. package/src/components/TextInput/TextInput.tsx +8 -8
  91. package/src/components/Textarea/Textarea.tsx +7 -8
  92. package/src/components/ValidationSummary/ValidationSummary.tsx +12 -5
  93. package/src/hooks/useSlots.ts +37 -9
  94. package/src/types/index.ts +18 -14
  95. package/src/utils/index.ts +8 -6
  96. package/dist/node_modules/merge-refs/dist/index.js +0 -36
@@ -13,7 +13,7 @@ import clsx from "clsx"
13
13
  import { useCallback, useMemo, useReducer } from "react"
14
14
  import { DayPicker } from "react-day-picker"
15
15
 
16
- import type { ComponentConfig, StandardSizes } from "../../types"
16
+ import type { StandardSizes } from "../../types"
17
17
  import type {
18
18
  DateRange,
19
19
  DateRangeStr,
@@ -23,8 +23,8 @@ import type {
23
23
  TDateSingle,
24
24
  } from "./datepicker-utils"
25
25
 
26
- import { useId } from "../../hooks/useId"
27
26
  import Button from "../Button"
27
+ import { useField } from "../Field/Field.context"
28
28
  import { CalendarIcon, CrossIcon, TickIcon } from "../icons"
29
29
  import Popover from "../Popover"
30
30
  import TextInput from "../TextInput"
@@ -108,11 +108,6 @@ export interface DatePickerProps extends Omit<
108
108
 
109
109
  const now = new Date()
110
110
 
111
- const componentConfig: ComponentConfig = {
112
- fieldSuffix: "_display",
113
- isField: true,
114
- }
115
-
116
111
  const baseValueProps = {
117
112
  readOnly: true,
118
113
  type: "hidden",
@@ -162,7 +157,7 @@ const Calendar = ({
162
157
  )
163
158
  }
164
159
 
165
- export const DatePicker = ({
160
+ const DatePicker = ({
166
161
  className,
167
162
  closeOnSelect = true,
168
163
  dateFormat = "dd/MM/yyyy",
@@ -183,7 +178,7 @@ export const DatePicker = ({
183
178
  startDate,
184
179
  ...props
185
180
  }: DatePickerProps): JSX.Element => {
186
- const uid = useId(id)
181
+ const field = useField()
187
182
 
188
183
  initialDate = getInitialDate(mode, initialDate)
189
184
 
@@ -285,7 +280,7 @@ export const DatePicker = ({
285
280
 
286
281
  const valueProps = {
287
282
  ...baseValueProps,
288
- id: uid,
283
+ id: id ?? field?.id,
289
284
  name: name,
290
285
  }
291
286
 
@@ -309,9 +304,9 @@ export const DatePicker = ({
309
304
  autoComplete="off"
310
305
  className="coop-datepicker-input"
311
306
  disabled={disabled}
312
- id={uid + componentConfig.fieldSuffix}
307
+ id={valueProps.id + "_display"}
313
308
  //maxLength={dateFormat.length}
314
- name={name + componentConfig.fieldSuffix}
309
+ name={name + "_display"}
315
310
  onChange={updateFromInput}
316
311
  placeholder={getPlaceholder()}
317
312
  ref={ref}
@@ -381,13 +376,13 @@ export const DatePicker = ({
381
376
  <>
382
377
  <input
383
378
  {...baseValueProps}
384
- id={`${uid}_start`}
379
+ id={`${valueProps.id}_start`}
385
380
  name={`${name}_start`}
386
381
  value={state.range?.field?.from ?? state.range?.input ?? ""}
387
382
  />
388
383
  <input
389
384
  {...baseValueProps}
390
- id={`${uid}_end`}
385
+ id={`${valueProps.id}_end`}
391
386
  name={`${name}_end`}
392
387
  value={state.range?.field?.to ?? state.range?.input ?? ""}
393
388
  />
@@ -397,6 +392,11 @@ export const DatePicker = ({
397
392
  )
398
393
  }
399
394
 
400
- DatePicker.config = componentConfig
395
+ DatePicker.slot = {
396
+ field: true,
397
+ name: "DatePicker",
398
+ suffix: "_display",
399
+ }
401
400
 
402
401
  export default DatePicker
402
+ export { DatePicker }
@@ -34,12 +34,7 @@ const componentSlots = {
34
34
  ExpandableSummary: null,
35
35
  }
36
36
 
37
- export const Expandable = ({
38
- children,
39
- className,
40
- ref,
41
- ...props
42
- }: ExpandableProps): JSX.Element => {
37
+ const Expandable = ({ children, className, ref, ...props }: ExpandableProps): JSX.Element => {
43
38
  const slots = useSlots(componentSlots, children)
44
39
 
45
40
  const componentProps = {
@@ -76,10 +71,12 @@ const ExpandableContent = ({ children, className, ...props }: ExpandableContentP
76
71
  )
77
72
  }
78
73
 
79
- ExpandableSummary.config = { name: "ExpandableSummary" }
80
- ExpandableContent.config = { name: "ExpandableContent" }
74
+ Expandable.slot = { name: "Expandable" }
75
+ ExpandableSummary.slot = { name: "ExpandableSummary" }
76
+ ExpandableContent.slot = { name: "ExpandableContent" }
81
77
 
82
78
  Expandable.Summary = ExpandableSummary
83
79
  Expandable.Content = ExpandableContent
84
80
 
85
81
  export default Expandable
82
+ export { Expandable, ExpandableContent, ExpandableSummary }
@@ -0,0 +1,29 @@
1
+ "use client"
2
+ import { createContext, useContext } from "react"
3
+
4
+ export interface FieldConfig {
5
+ disabled: boolean
6
+ id: string
7
+ inline?: boolean
8
+ suffix?: string
9
+ }
10
+
11
+ export interface FieldContextValue {
12
+ // register: ({ control, inline, suffix, uid }: FieldConfig) => void
13
+ disabled?: boolean
14
+ id?: string
15
+ inline?: boolean
16
+ suffix?: string
17
+ }
18
+
19
+ export const FieldContext = createContext<FieldContextValue | null>(null)
20
+
21
+ export const useField = () => {
22
+ const context = useContext(FieldContext)
23
+
24
+ if (!context) {
25
+ return null
26
+ }
27
+
28
+ return context
29
+ }
@@ -1,14 +1,17 @@
1
- import type { HTMLAttributes, HTMLProps, Ref } from "react"
1
+ "use client"
2
+ import type { HTMLAttributes, Ref } from "react"
2
3
 
3
4
  import clsx from "clsx"
4
5
  import React from "react"
5
6
 
6
7
  import { useId } from "../../hooks/useId"
7
8
  import { useSlots } from "../../hooks/useSlots"
8
- import { ReactNodeWithConfig } from "../../types"
9
+ import { SlotConfig } from "../../types"
10
+ import { getSlotProp } from "../../utils"
9
11
  import { Error as BaseError, type ErrorProps } from "../FieldMarkers/Error"
10
12
  import { Hint as BaseHint, type HintProps } from "../FieldMarkers/Hint"
11
13
  import { Label as BaseLabel, type LabelProps } from "../FieldMarkers/Label"
14
+ import { FieldConfig, FieldContext } from "./Field.context"
12
15
 
13
16
  const componentSlots = {
14
17
  Children: null,
@@ -35,7 +38,7 @@ interface FieldProps extends HTMLAttributes<HTMLDivElement> {
35
38
  ref?: Ref<HTMLDivElement>
36
39
  }
37
40
 
38
- export const Field = ({
41
+ const Field = ({
39
42
  boxed = false,
40
43
  children,
41
44
  className,
@@ -47,85 +50,87 @@ export const Field = ({
47
50
  const slots = { ...useSlots(componentSlots, children) }
48
51
  const hasMarkers = !!(slots.FieldLabel ?? slots.FieldError ?? slots.FieldHint)
49
52
 
50
- let isInline = false
51
- let control: ReactNodeWithConfig
52
- let controlSuffix = ""
53
- let controlId = useId()
54
- let controlDisabled = false
53
+ const internalId = useId()
55
54
 
56
- if (Array.isArray(slots.Children)) {
57
- slots.Children = slots.Children.filter((child: ReactNodeWithConfig) => {
58
- if (child?.type?.config?.isField) {
59
- control = child
60
- return false
61
- }
62
- return true
63
- })
55
+ const controlProps: FieldConfig = {
56
+ disabled: false,
57
+ id: internalId,
64
58
  }
65
59
 
66
- if (React.isValidElement(control)) {
67
- const controlProps = control.props as HTMLProps<HTMLElement>
60
+ if (Array.isArray(slots.Children)) {
61
+ slots.Children = slots.Children.filter((child: React.ReactNode) => {
62
+ //resolveComponentName(child)
68
63
 
69
- controlId = controlProps.id ?? controlId
70
- controlDisabled = controlProps.disabled ?? false
71
- controlSuffix = control?.type?.config?.fieldSuffix ?? ""
72
- isInline = control?.type?.config?.isInline ?? false
64
+ if (child && typeof child === "object" && "type" in child) {
65
+ if (typeof child?.type === "function" && "slot" in child.type) {
66
+ const { slot } = child?.type as { slot: SlotConfig }
73
67
 
74
- slots.Control = controlProps.id
75
- ? control
76
- : React.cloneElement(control as React.ReactElement<HTMLInputElement>, { id: controlId })
77
- }
68
+ slots.Control = child
78
69
 
79
- if (React.isValidElement(slots.FieldLabel) && !(slots.FieldLabel.props as LabelProps).htmlFor) {
80
- slots.FieldLabel = React.cloneElement(slots.FieldLabel as React.ReactElement<LabelProps>, {
81
- htmlFor: controlId + controlSuffix,
70
+ if (slots.Control.props) {
71
+ controlProps.inline = slot.inline ?? false
72
+ controlProps.disabled = getSlotProp<boolean>(slots.Control, "disabled") ?? false
73
+ controlProps.id = getSlotProp<string>(slots.Control, "id") ?? controlProps.id
74
+ controlProps.suffix = slot.suffix ?? undefined
75
+ }
76
+
77
+ return false
78
+ }
79
+ }
80
+
81
+ return true
82
82
  })
83
83
  }
84
84
 
85
85
  const componentProps = {
86
86
  ...props,
87
- "aria-disabled": controlDisabled || undefined,
88
- className: clsx("coop-field", isInline && "coop-field-inline", className),
87
+ "aria-disabled": controlProps.disabled || undefined,
88
+ className: clsx("coop-field", controlProps.inline && "coop-field-inline", className),
89
89
  "data-boxed": boxed || undefined,
90
90
  "data-error": error || undefined,
91
91
  "data-hide-error": hideErrorBar || undefined,
92
92
  }
93
93
 
94
94
  return (
95
- <div {...componentProps} ref={ref}>
96
- {!isInline && hasMarkers && (
97
- <div className="coop-field-markers">
98
- {slots.FieldLabel}
99
- {slots.FieldHint}
100
- {slots.FieldError}
101
- </div>
102
- )}
103
- {slots.Control && (
104
- <div className="coop-field-control">
105
- {slots.Control}
106
- {isInline && hasMarkers && (
107
- <div className="coop-field-markers">
108
- {slots.FieldLabel}
109
- {slots.FieldHint}
110
- {slots.FieldError}
111
- </div>
112
- )}
113
- </div>
114
- )}
115
- {slots.Children}
116
- </div>
95
+ <FieldContext.Provider value={{ ...controlProps }}>
96
+ <div {...componentProps} ref={ref}>
97
+ {!controlProps?.inline && hasMarkers && (
98
+ <div className="coop-field-markers">
99
+ {slots.FieldLabel}
100
+ {slots.FieldHint}
101
+ {slots.FieldError}
102
+ </div>
103
+ )}
104
+ {slots.Control && (
105
+ <div className="coop-field-control">
106
+ {slots.Control}
107
+ {controlProps?.inline && hasMarkers && (
108
+ <div className="coop-field-markers">
109
+ {slots.FieldLabel}
110
+ {slots.FieldHint}
111
+ {slots.FieldError}
112
+ </div>
113
+ )}
114
+ </div>
115
+ )}
116
+ {slots.Children}
117
+ </div>
118
+ </FieldContext.Provider>
117
119
  )
118
120
  }
121
+
119
122
  const FieldLabel = (props: LabelProps) => <BaseLabel {...props} />
120
123
  const FieldHint = (props: HintProps) => <BaseHint {...props} />
121
124
  const FieldError = (props: ErrorProps) => <BaseError {...props} />
122
125
 
123
- FieldLabel.config = { name: "FieldLabel" }
124
- FieldHint.config = { name: "FieldHint" }
125
- FieldError.config = { name: "FieldError" }
126
+ Field.slot = { name: "Field" }
127
+ FieldLabel.slot = { name: "FieldLabel" }
128
+ FieldHint.slot = { name: "FieldHint" }
129
+ FieldError.slot = { name: "FieldError" }
126
130
 
127
131
  Field.Label = FieldLabel
128
132
  Field.Hint = FieldHint
129
133
  Field.Error = FieldError
130
134
 
131
135
  export default Field
136
+ export { Field, FieldError, FieldHint, FieldLabel }
@@ -1,6 +1,8 @@
1
1
  import clsx from "clsx"
2
2
  import { LabelHTMLAttributes, Ref } from "react"
3
3
 
4
+ import { useField } from "../Field/Field.context"
5
+
4
6
  export interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {
5
7
  /** **(Optional)** Main label for the form element. Accepts any valid JSX or string. */
6
8
  children?: string | React.ReactNode
@@ -13,8 +15,10 @@ export interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {
13
15
  }
14
16
 
15
17
  export const Label = ({ children, className, isVisible = true, ref, ...props }: LabelProps) => {
18
+ const field = useField()
16
19
  const componentProps = {
17
20
  className: clsx("coop-field-label", !isVisible && "sr-only", className),
21
+ htmlFor: props.htmlFor ?? (field?.id ? field.id + (field?.suffix ?? "") : undefined),
18
22
  ...props,
19
23
  }
20
24
  return (
@@ -24,7 +24,7 @@ export interface FieldsetProps extends FieldsetHTMLAttributes<HTMLFieldSetElemen
24
24
  /** **(Optional)** Specify the size of the Fieldset and all its descendents. */
25
25
  size?: StandardSizes
26
26
  }
27
- export const Fieldset = ({
27
+ const Fieldset = ({
28
28
  children,
29
29
  className,
30
30
  disabled,
@@ -83,10 +83,11 @@ const FieldsetLegend = (props: LegendProps) => <BaseLegend {...props} />
83
83
  const FieldsetHint = (props: HintProps) => <BaseHint {...props} />
84
84
  const FieldsetError = (props: ErrorProps) => <BaseError {...props} />
85
85
 
86
- FieldsetFields.config = { name: "FieldsetField" }
87
- FieldsetLegend.config = { name: "FieldsetLegend" }
88
- FieldsetHint.config = { name: "FieldsetHint" }
89
- FieldsetError.config = { name: "FieldsetError" }
86
+ Fieldset.slot = { name: "Fieldset" }
87
+ FieldsetFields.slot = { name: "FieldsetField" }
88
+ FieldsetLegend.slot = { name: "FieldsetLegend" }
89
+ FieldsetHint.slot = { name: "FieldsetHint" }
90
+ FieldsetError.slot = { name: "FieldsetError" }
90
91
 
91
92
  Fieldset.Error = FieldsetError
92
93
  Fieldset.Fields = FieldsetFields
@@ -94,3 +95,4 @@ Fieldset.Hint = FieldsetHint
94
95
  Fieldset.Legend = FieldsetLegend
95
96
 
96
97
  export default Fieldset
98
+ export { Fieldset, FieldsetError, FieldsetFields, FieldsetHint, FieldsetLegend }
@@ -15,7 +15,7 @@ export interface FlourishProps extends SVGProps<SVGSVGElement> {
15
15
  ref?: Ref<SVGSVGElement>
16
16
  }
17
17
 
18
- export const Flourish = ({
18
+ const Flourish = ({
19
19
  children,
20
20
  className,
21
21
  fill = "brand-blue",
@@ -38,4 +38,7 @@ export const Flourish = ({
38
38
  )
39
39
  }
40
40
 
41
+ Flourish.slot = { name: "Flourish" }
42
+
41
43
  export default Flourish
44
+ export { Flourish }
@@ -11,7 +11,7 @@ export interface FormProps extends FormHTMLAttributes<HTMLFormElement> {
11
11
  ref?: Ref<HTMLFormElement>
12
12
  }
13
13
 
14
- export const Form = ({ children, className, ref, ...props }: FormProps): JSX.Element => {
14
+ const Form = ({ children, className, ref, ...props }: FormProps): JSX.Element => {
15
15
  const componentProps = {
16
16
  className: clsx("coop-form ", className),
17
17
  ...props,
@@ -24,4 +24,7 @@ export const Form = ({ children, className, ref, ...props }: FormProps): JSX.Ele
24
24
  )
25
25
  }
26
26
 
27
+ Form.slot = { name: "Form" }
28
+
27
29
  export default Form
30
+ export { Form }
@@ -36,7 +36,7 @@ const getContentfulParams = (src: string, width: string, height: string | undefi
36
36
  }
37
37
  }
38
38
 
39
- export const Image = ({
39
+ const Image = ({
40
40
  alt,
41
41
  crop,
42
42
  height,
@@ -64,4 +64,7 @@ export const Image = ({
64
64
  )
65
65
  }
66
66
 
67
+ Image.slot = { name: "Image" }
68
+
67
69
  export default Image
70
+ export { Image }
@@ -35,7 +35,7 @@ const componentSlots = {
35
35
  PillBadge: null,
36
36
  }
37
37
 
38
- export const Pill = ({
38
+ const Pill = ({
39
39
  as,
40
40
  children,
41
41
  className,
@@ -66,8 +66,10 @@ const PillBadge = ({ children, className }: PillBadgeProps) => {
66
66
  )
67
67
  }
68
68
 
69
- PillBadge.config = { name: "PillBadge" }
69
+ Pill.slot = { name: "Pill" }
70
+ PillBadge.slot = { name: "PillBadge" }
70
71
 
71
72
  Pill.Badge = PillBadge
72
73
 
73
74
  export default Pill
75
+ export { Pill, PillBadge }
@@ -76,7 +76,7 @@ const componentSlots = {
76
76
  PopoverTrigger: null,
77
77
  }
78
78
 
79
- export const Popover = ({ children, ...props }: PopoverProps): JSX.Element => {
79
+ const Popover = ({ children, ...props }: PopoverProps): JSX.Element => {
80
80
  const slots = useSlots(componentSlots, children)
81
81
 
82
82
  return (
@@ -182,10 +182,11 @@ const PopoverAnchor = ({
182
182
  return <RadixPopover.Anchor {...componentProps}>{children}</RadixPopover.Anchor>
183
183
  }
184
184
 
185
- PopoverTrigger.config = { name: "PopoverTrigger" }
186
- PopoverContent.config = { name: "PopoverContent" }
187
- PopoverClose.config = { name: "PopoverClose" }
188
- PopoverAnchor.config = { name: "PopoverAnchor" }
185
+ Popover.slot = { name: "Popover" }
186
+ PopoverTrigger.slot = { name: "PopoverTrigger" }
187
+ PopoverContent.slot = { name: "PopoverContent" }
188
+ PopoverClose.slot = { name: "PopoverClose" }
189
+ PopoverAnchor.slot = { name: "PopoverAnchor" }
189
190
 
190
191
  Popover.Trigger = PopoverTrigger
191
192
  Popover.Content = PopoverContent
@@ -193,3 +194,4 @@ Popover.Close = PopoverClose
193
194
  Popover.Anchor = PopoverAnchor
194
195
 
195
196
  export default Popover
197
+ export { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger }
@@ -1,8 +1,9 @@
1
+ "use client"
1
2
  import clsx from "clsx"
2
3
  import { type InputHTMLAttributes, type JSX, Ref } from "react"
3
4
 
4
- import { useId } from "../../hooks/useId"
5
- import { ComponentConfig, StandardSizes } from "../../types"
5
+ import { StandardSizes } from "../../types"
6
+ import { useField } from "../Field/Field.context"
6
7
 
7
8
  export interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "type"> {
8
9
  /** **(Optional)** Specify additional CSS classes to be applied to the component. */
@@ -21,7 +22,7 @@ export interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>,
21
22
  size?: StandardSizes
22
23
  }
23
24
 
24
- export const Radio = ({
25
+ const Radio = ({
25
26
  className,
26
27
  disabled,
27
28
  error = false,
@@ -31,14 +32,14 @@ export const Radio = ({
31
32
  size,
32
33
  ...props
33
34
  }: RadioProps): JSX.Element => {
34
- const uid = useId(id)
35
+ const field = useField()
35
36
 
36
37
  const componentProps = {
37
38
  className: clsx("coop-radio", "coop-field-element", className),
38
39
  "data-error": error || undefined,
39
40
  "data-size": size ?? undefined,
40
41
  disabled,
41
- id: uid,
42
+ id: id ?? field?.id,
42
43
  name,
43
44
  type: "radio",
44
45
  ...props,
@@ -47,9 +48,11 @@ export const Radio = ({
47
48
  return <input {...componentProps} ref={ref} />
48
49
  }
49
50
 
50
- Radio.config = {
51
- isField: true,
52
- isInline: true,
53
- } satisfies ComponentConfig
51
+ Radio.slot = {
52
+ field: true,
53
+ inline: true,
54
+ name: "Radio",
55
+ }
54
56
 
55
57
  export default Radio
58
+ export { Radio }
@@ -1,4 +1,4 @@
1
- export const RootSVG = () => {
1
+ const RootSVG = () => {
2
2
  return (
3
3
  <svg
4
4
  height="0"
@@ -20,4 +20,7 @@ export const RootSVG = () => {
20
20
  )
21
21
  }
22
22
 
23
+ RootSVG.slot = { name: "RootSVG" }
24
+
23
25
  export default RootSVG
26
+ export { RootSVG }
@@ -0,0 +1,20 @@
1
+ import { createContext, RefObject, useContext } from "react"
2
+
3
+ import { StandardSizes } from "../../types"
4
+
5
+ interface SearchboxContextValue {
6
+ buttonId?: string
7
+ id?: string
8
+ inputId?: string
9
+ isLoading?: boolean
10
+ ref?: RefObject<HTMLFormElement | null> | null
11
+ size?: StandardSizes
12
+ }
13
+
14
+ export const SearchboxContext = createContext<SearchboxContextValue>({})
15
+
16
+ export const useSearchbox = () => {
17
+ const context = useContext(SearchboxContext)
18
+ if (!context) throw new Error("Searchbox components must be used inside <Searchbox>")
19
+ return context
20
+ }