@seed-design/react 1.1.17 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/lib/components/AspectRatio/AspectRatio.cjs +53 -0
  2. package/lib/components/AspectRatio/AspectRatio.d.ts +11 -0
  3. package/lib/components/AspectRatio/AspectRatio.d.ts.map +1 -0
  4. package/lib/components/AspectRatio/AspectRatio.js +30 -0
  5. package/lib/components/AspectRatio/index.cjs +9 -0
  6. package/lib/components/AspectRatio/index.d.ts +2 -0
  7. package/lib/components/AspectRatio/index.d.ts.map +1 -0
  8. package/lib/components/AspectRatio/index.js +1 -0
  9. package/lib/components/Avatar/Avatar.cjs +4 -10
  10. package/lib/components/Avatar/Avatar.d.ts +4 -4
  11. package/lib/components/Avatar/Avatar.d.ts.map +1 -1
  12. package/lib/components/Avatar/Avatar.js +4 -10
  13. package/lib/components/BottomSheet/BottomSheet.cjs +1 -1
  14. package/lib/components/BottomSheet/BottomSheet.d.ts +1 -1
  15. package/lib/components/BottomSheet/BottomSheet.d.ts.map +1 -1
  16. package/lib/components/BottomSheet/BottomSheet.js +1 -1
  17. package/lib/components/Checkbox/Checkbox.cjs +5 -0
  18. package/lib/components/Checkbox/Checkbox.d.ts +4 -0
  19. package/lib/components/Checkbox/Checkbox.d.ts.map +1 -1
  20. package/lib/components/Checkbox/Checkbox.js +5 -1
  21. package/lib/components/Checkbox/Checkbox.namespace.cjs +1 -0
  22. package/lib/components/Checkbox/Checkbox.namespace.d.ts +1 -1
  23. package/lib/components/Checkbox/Checkbox.namespace.d.ts.map +1 -1
  24. package/lib/components/Checkbox/Checkbox.namespace.js +1 -1
  25. package/lib/components/Checkbox/index.cjs +1 -0
  26. package/lib/components/Checkbox/index.d.ts +1 -1
  27. package/lib/components/Checkbox/index.d.ts.map +1 -1
  28. package/lib/components/Checkbox/index.js +1 -1
  29. package/lib/components/Dialog/Dialog.d.ts.map +1 -1
  30. package/lib/components/Fieldset/Fieldset.cjs +86 -0
  31. package/lib/components/Fieldset/Fieldset.d.ts +30 -0
  32. package/lib/components/Fieldset/Fieldset.d.ts.map +1 -0
  33. package/lib/components/Fieldset/Fieldset.js +75 -0
  34. package/lib/components/Fieldset/Fieldset.namespace.cjs +16 -0
  35. package/lib/components/Fieldset/Fieldset.namespace.d.ts +2 -0
  36. package/lib/components/Fieldset/Fieldset.namespace.d.ts.map +1 -0
  37. package/lib/components/Fieldset/Fieldset.namespace.js +1 -0
  38. package/lib/components/Fieldset/index.cjs +18 -0
  39. package/lib/components/Fieldset/index.d.ts +3 -0
  40. package/lib/components/Fieldset/index.d.ts.map +1 -0
  41. package/lib/components/Fieldset/index.js +3 -0
  42. package/lib/components/Grid/Grid.cjs +56 -0
  43. package/lib/components/Grid/Grid.d.ts +41 -0
  44. package/lib/components/Grid/Grid.d.ts.map +1 -0
  45. package/lib/components/Grid/Grid.js +33 -0
  46. package/lib/components/Grid/index.cjs +9 -0
  47. package/lib/components/Grid/index.d.ts +2 -0
  48. package/lib/components/Grid/index.d.ts.map +1 -0
  49. package/lib/components/Grid/index.js +1 -0
  50. package/lib/components/GridItem/GridItem.cjs +45 -0
  51. package/lib/components/GridItem/GridItem.d.ts +35 -0
  52. package/lib/components/GridItem/GridItem.d.ts.map +1 -0
  53. package/lib/components/GridItem/GridItem.js +22 -0
  54. package/lib/components/GridItem/index.cjs +9 -0
  55. package/lib/components/GridItem/index.d.ts +2 -0
  56. package/lib/components/GridItem/index.d.ts.map +1 -0
  57. package/lib/components/GridItem/index.js +1 -0
  58. package/lib/components/HelpBubble/HelpBubble.cjs +5 -0
  59. package/lib/components/HelpBubble/HelpBubble.d.ts +3 -0
  60. package/lib/components/HelpBubble/HelpBubble.d.ts.map +1 -1
  61. package/lib/components/HelpBubble/HelpBubble.js +5 -1
  62. package/lib/components/HelpBubble/HelpBubble.namespace.cjs +1 -0
  63. package/lib/components/HelpBubble/HelpBubble.namespace.d.ts +1 -1
  64. package/lib/components/HelpBubble/HelpBubble.namespace.d.ts.map +1 -1
  65. package/lib/components/HelpBubble/HelpBubble.namespace.js +1 -1
  66. package/lib/components/HelpBubble/index.cjs +1 -0
  67. package/lib/components/HelpBubble/index.d.ts +1 -1
  68. package/lib/components/HelpBubble/index.d.ts.map +1 -1
  69. package/lib/components/HelpBubble/index.js +1 -1
  70. package/lib/components/ImageFrame/ImageFrame.cjs +157 -0
  71. package/lib/components/ImageFrame/ImageFrame.d.ts +51 -0
  72. package/lib/components/ImageFrame/ImageFrame.d.ts.map +1 -0
  73. package/lib/components/ImageFrame/ImageFrame.js +129 -0
  74. package/lib/components/ImageFrame/index.cjs +14 -0
  75. package/lib/components/ImageFrame/index.d.ts +2 -0
  76. package/lib/components/ImageFrame/index.d.ts.map +1 -0
  77. package/lib/components/ImageFrame/index.js +1 -0
  78. package/lib/components/MenuSheet/MenuSheet.cjs +60 -24
  79. package/lib/components/MenuSheet/MenuSheet.d.ts +12 -0
  80. package/lib/components/MenuSheet/MenuSheet.d.ts.map +1 -1
  81. package/lib/components/MenuSheet/MenuSheet.js +57 -25
  82. package/lib/components/MenuSheet/MenuSheet.namespace.cjs +4 -0
  83. package/lib/components/MenuSheet/MenuSheet.namespace.d.ts +1 -1
  84. package/lib/components/MenuSheet/MenuSheet.namespace.d.ts.map +1 -1
  85. package/lib/components/MenuSheet/MenuSheet.namespace.js +1 -1
  86. package/lib/components/MenuSheet/index.cjs +4 -0
  87. package/lib/components/MenuSheet/index.d.ts +1 -1
  88. package/lib/components/MenuSheet/index.d.ts.map +1 -1
  89. package/lib/components/MenuSheet/index.js +1 -1
  90. package/lib/components/RadioGroup/RadioGroup.cjs +4 -1
  91. package/lib/components/RadioGroup/RadioGroup.d.ts +3 -2
  92. package/lib/components/RadioGroup/RadioGroup.d.ts.map +1 -1
  93. package/lib/components/RadioGroup/RadioGroup.js +4 -1
  94. package/lib/components/RadioGroupField/RadioGroupField.cjs +79 -0
  95. package/lib/components/RadioGroupField/RadioGroupField.d.ts +30 -0
  96. package/lib/components/RadioGroupField/RadioGroupField.d.ts.map +1 -0
  97. package/lib/components/RadioGroupField/RadioGroupField.js +68 -0
  98. package/lib/components/RadioGroupField/RadioGroupField.namespace.cjs +16 -0
  99. package/lib/components/RadioGroupField/RadioGroupField.namespace.d.ts +2 -0
  100. package/lib/components/RadioGroupField/RadioGroupField.namespace.d.ts.map +1 -0
  101. package/lib/components/RadioGroupField/RadioGroupField.namespace.js +1 -0
  102. package/lib/components/RadioGroupField/index.cjs +18 -0
  103. package/lib/components/RadioGroupField/index.d.ts +3 -0
  104. package/lib/components/RadioGroupField/index.d.ts.map +1 -0
  105. package/lib/components/RadioGroupField/index.js +3 -0
  106. package/lib/components/SelectBox/CheckSelectBox.cjs +117 -8
  107. package/lib/components/SelectBox/CheckSelectBox.d.ts +38 -10
  108. package/lib/components/SelectBox/CheckSelectBox.d.ts.map +1 -1
  109. package/lib/components/SelectBox/CheckSelectBox.js +113 -10
  110. package/lib/components/SelectBox/CheckSelectBox.namespace.cjs +6 -0
  111. package/lib/components/SelectBox/CheckSelectBox.namespace.d.ts +1 -1
  112. package/lib/components/SelectBox/CheckSelectBox.namespace.d.ts.map +1 -1
  113. package/lib/components/SelectBox/CheckSelectBox.namespace.js +1 -1
  114. package/lib/components/SelectBox/RadioSelectBox.cjs +112 -9
  115. package/lib/components/SelectBox/RadioSelectBox.d.ts +31 -7
  116. package/lib/components/SelectBox/RadioSelectBox.d.ts.map +1 -1
  117. package/lib/components/SelectBox/RadioSelectBox.js +109 -10
  118. package/lib/components/SelectBox/RadioSelectBox.namespace.cjs +5 -1
  119. package/lib/components/SelectBox/RadioSelectBox.namespace.d.ts +1 -1
  120. package/lib/components/SelectBox/RadioSelectBox.namespace.d.ts.map +1 -1
  121. package/lib/components/SelectBox/RadioSelectBox.namespace.js +1 -1
  122. package/lib/components/SelectBox/index.cjs +11 -1
  123. package/lib/components/SelectBox/index.d.ts +2 -2
  124. package/lib/components/SelectBox/index.d.ts.map +1 -1
  125. package/lib/components/SelectBox/index.js +2 -2
  126. package/lib/components/Switch/Switch.cjs +5 -5
  127. package/lib/components/Switch/Switch.d.ts +3 -3
  128. package/lib/components/Switch/Switch.d.ts.map +1 -1
  129. package/lib/components/Switch/Switch.js +5 -5
  130. package/lib/components/TagGroup/TagGroup.cjs +25 -9
  131. package/lib/components/TagGroup/TagGroup.d.ts +5 -1
  132. package/lib/components/TagGroup/TagGroup.d.ts.map +1 -1
  133. package/lib/components/TagGroup/TagGroup.js +25 -10
  134. package/lib/components/TagGroup/TagGroup.namespace.cjs +1 -0
  135. package/lib/components/TagGroup/TagGroup.namespace.d.ts +1 -1
  136. package/lib/components/TagGroup/TagGroup.namespace.d.ts.map +1 -1
  137. package/lib/components/TagGroup/TagGroup.namespace.js +1 -1
  138. package/lib/components/TagGroup/index.cjs +1 -0
  139. package/lib/components/TagGroup/index.d.ts +1 -1
  140. package/lib/components/TagGroup/index.d.ts.map +1 -1
  141. package/lib/components/TagGroup/index.js +1 -1
  142. package/lib/components/index.cjs +53 -1
  143. package/lib/components/index.d.ts +6 -0
  144. package/lib/components/index.d.ts.map +1 -1
  145. package/lib/components/index.js +16 -6
  146. package/lib/index.cjs +53 -1
  147. package/lib/index.js +16 -6
  148. package/lib/utils/styled.cjs +6 -0
  149. package/lib/utils/styled.d.ts +6 -0
  150. package/lib/utils/styled.d.ts.map +1 -1
  151. package/lib/utils/styled.js +6 -0
  152. package/package.json +6 -3
  153. package/src/components/AspectRatio/AspectRatio.tsx +38 -0
  154. package/src/components/AspectRatio/index.ts +1 -0
  155. package/src/components/Avatar/Avatar.tsx +7 -14
  156. package/src/components/BottomSheet/BottomSheet.tsx +2 -4
  157. package/src/components/Checkbox/Checkbox.namespace.ts +2 -0
  158. package/src/components/Checkbox/Checkbox.tsx +15 -0
  159. package/src/components/Checkbox/index.ts +2 -0
  160. package/src/components/Dialog/Dialog.tsx +6 -0
  161. package/src/components/Fieldset/Fieldset.namespace.ts +17 -0
  162. package/src/components/Fieldset/Fieldset.tsx +101 -0
  163. package/src/components/Fieldset/index.ts +19 -0
  164. package/src/components/Grid/Grid.tsx +79 -0
  165. package/src/components/Grid/index.ts +1 -0
  166. package/src/components/GridItem/GridItem.tsx +70 -0
  167. package/src/components/GridItem/index.ts +1 -0
  168. package/src/components/HelpBubble/HelpBubble.namespace.ts +3 -0
  169. package/src/components/HelpBubble/HelpBubble.tsx +7 -2
  170. package/src/components/HelpBubble/index.ts +2 -0
  171. package/src/components/ImageFrame/ImageFrame.tsx +227 -0
  172. package/src/components/ImageFrame/index.ts +14 -0
  173. package/src/components/MenuSheet/MenuSheet.namespace.ts +8 -0
  174. package/src/components/MenuSheet/MenuSheet.tsx +82 -34
  175. package/src/components/MenuSheet/index.ts +8 -0
  176. package/src/components/RadioGroup/RadioGroup.tsx +8 -2
  177. package/src/components/RadioGroupField/RadioGroupField.namespace.ts +18 -0
  178. package/src/components/RadioGroupField/RadioGroupField.tsx +114 -0
  179. package/src/components/RadioGroupField/index.ts +2 -0
  180. package/src/components/SelectBox/CheckSelectBox.namespace.ts +12 -0
  181. package/src/components/SelectBox/CheckSelectBox.tsx +229 -24
  182. package/src/components/SelectBox/RadioSelectBox.namespace.ts +10 -2
  183. package/src/components/SelectBox/RadioSelectBox.tsx +210 -16
  184. package/src/components/SelectBox/index.ts +22 -2
  185. package/src/components/Switch/Switch.tsx +7 -7
  186. package/src/components/TagGroup/TagGroup.namespace.ts +2 -0
  187. package/src/components/TagGroup/TagGroup.tsx +33 -9
  188. package/src/components/TagGroup/index.ts +2 -0
  189. package/src/components/index.ts +6 -0
  190. package/src/utils/styled.tsx +18 -0
@@ -1,35 +1,154 @@
1
- import { selectBox } from "@seed-design/css/recipes/select-box";
2
- import { selectBoxGroup } from "@seed-design/css/recipes/select-box-group";
1
+ import { composeRefs } from "@radix-ui/react-compose-refs";
2
+ import { selectBox, type SelectBoxVariantProps } from "@seed-design/css/recipes/select-box";
3
+ import {
4
+ selectBoxCheckmark,
5
+ type SelectBoxCheckmarkVariantProps,
6
+ } from "@seed-design/css/recipes/selectBoxCheckmark";
7
+ import {
8
+ selectBoxGroup,
9
+ type SelectBoxGroupVariantProps,
10
+ } from "@seed-design/css/recipes/select-box-group";
3
11
  import { Checkbox as CheckboxPrimitive, useCheckboxContext } from "@seed-design/react-checkbox";
12
+ import {
13
+ Collapsible,
14
+ CollapsibleProvider,
15
+ useCollapsible,
16
+ useCollapsibleContext,
17
+ } from "@seed-design/react-collapsible";
4
18
  import { Primitive, type PrimitiveProps } from "@seed-design/react-primitive";
5
- import { forwardRef } from "react";
6
- import { createRecipeContext } from "../../utils/createRecipeContext";
19
+ import clsx from "clsx";
20
+ import {
21
+ createContext,
22
+ forwardRef,
23
+ useCallback,
24
+ useContext,
25
+ useState,
26
+ type PropsWithChildren,
27
+ } from "react";
7
28
  import { createSlotRecipeContext } from "../../utils/createSlotRecipeContext";
8
29
  import { createWithStateProps } from "../../utils/createWithStateProps";
30
+ import { InternalIcon, type InternalIconProps } from "../private/Icon";
31
+
32
+ const { PropsProvider, ClassNamesProvider, withContext, useProps, useClassNames } =
33
+ createSlotRecipeContext(selectBox);
9
34
 
10
- const { withContext: withGroupContext } = createRecipeContext(selectBoxGroup);
11
- const { withContext, withProvider } = createSlotRecipeContext(selectBox);
12
35
  const withStateProps = createWithStateProps([useCheckboxContext]);
13
36
 
37
+ const FooterContext = createContext<{
38
+ isFooterRendered: boolean;
39
+ footerRef: (node: HTMLDivElement | null) => void;
40
+ footerVisibility: Exclude<NonNullable<CheckSelectBoxRootProps["footerVisibility"]>, "always">;
41
+ } | null>(null);
14
42
  export interface CheckSelectBoxGroupProps
15
- extends PrimitiveProps,
16
- React.HTMLAttributes<HTMLDivElement> {}
43
+ extends SelectBoxGroupVariantProps,
44
+ PrimitiveProps,
45
+ React.HTMLAttributes<HTMLDivElement> {
46
+ /**
47
+ * Number of columns in the grid layout. When bigger than 1, child `CheckSelectBoxRoot` will have a default layout of "vertical".
48
+ * @default 1
49
+ */
50
+ columns?: number;
51
+ }
52
+
53
+ export const CheckSelectBoxGroup = forwardRef<HTMLDivElement, CheckSelectBoxGroupProps>(
54
+ ({ columns = 1, className, style, ...props }, ref) => {
55
+ const [variantProps, otherProps] = selectBoxGroup.splitVariantProps(props);
56
+ const recipeClassName = selectBoxGroup(variantProps);
57
+ const layout = columns === 1 ? "horizontal" : "vertical";
58
+
59
+ return (
60
+ <PropsProvider value={{ layout }}>
61
+ <Primitive.div
62
+ ref={ref}
63
+ data-columns={columns}
64
+ className={clsx(recipeClassName, className)}
65
+ style={
66
+ {
67
+ ...style,
68
+ "--seed-select-box-group--columns": columns,
69
+ } as React.CSSProperties
70
+ }
71
+ {...otherProps}
72
+ />
73
+ </PropsProvider>
74
+ );
75
+ },
76
+ );
77
+
78
+ function FooterVisibilityProvider({
79
+ children,
80
+ footerVisibility,
81
+ }: PropsWithChildren<{
82
+ footerVisibility: Exclude<NonNullable<CheckSelectBoxRootProps["footerVisibility"]>, "always">;
83
+ }>) {
84
+ const { checked } = useCheckboxContext();
85
+
86
+ const collapsible = useCollapsible({
87
+ open: {
88
+ "when-selected": checked,
89
+ "when-not-selected": !checked,
90
+ }[footerVisibility],
91
+ });
92
+
93
+ const [isFooterRendered, setIsFooterRendered] = useState(false);
94
+ const footerRef = useCallback((node: HTMLDivElement | null) => {
95
+ setIsFooterRendered(!!node);
96
+ }, []);
97
+
98
+ return (
99
+ <CollapsibleProvider value={collapsible}>
100
+ <FooterContext.Provider value={{ isFooterRendered, footerRef, footerVisibility }}>
101
+ {children}
102
+ </FooterContext.Provider>
103
+ </CollapsibleProvider>
104
+ );
105
+ }
17
106
 
18
- /**
19
- * CheckSelectBoxGroup is a simple div wrapper for future extensibility.
20
- * It does not have spacing by default, nesting <VStack> under it is recommended.
21
- */
22
- export const CheckSelectBoxGroup = withGroupContext<HTMLDivElement, CheckSelectBoxGroupProps>(
23
- forwardRef<HTMLDivElement, CheckSelectBoxGroupProps>((props, ref) => (
24
- <Primitive.div ref={ref} role="group" {...props} />
25
- )),
107
+ export interface CheckSelectBoxRootProps
108
+ extends SelectBoxVariantProps,
109
+ CheckboxPrimitive.RootProps {
110
+ /**
111
+ * Controls when the footer is visible.
112
+ * @default "when-selected"
113
+ */
114
+ footerVisibility?: "when-selected" | "when-not-selected" | "always";
115
+ }
116
+
117
+ export const CheckSelectBoxRoot = forwardRef<HTMLLabelElement, CheckSelectBoxRootProps>(
118
+ ({ footerVisibility = "when-selected", className, children, ...props }, ref) => {
119
+ const [variantProps, otherProps] = selectBox.splitVariantProps(props);
120
+ const classNames = selectBox({
121
+ ...useProps(),
122
+ ...variantProps,
123
+ });
124
+
125
+ return (
126
+ <ClassNamesProvider value={classNames}>
127
+ <CheckboxPrimitive.Root
128
+ ref={ref}
129
+ className={clsx(classNames.root, className)}
130
+ {...otherProps}
131
+ >
132
+ {footerVisibility === "always" ? (
133
+ children
134
+ ) : (
135
+ <FooterVisibilityProvider footerVisibility={footerVisibility}>
136
+ {children}
137
+ </FooterVisibilityProvider>
138
+ )}
139
+ </CheckboxPrimitive.Root>
140
+ </ClassNamesProvider>
141
+ );
142
+ },
26
143
  );
27
144
 
28
- export interface CheckSelectBoxRootProps extends CheckboxPrimitive.RootProps {}
145
+ export interface CheckSelectBoxTriggerProps
146
+ extends PrimitiveProps,
147
+ React.HTMLAttributes<HTMLDivElement> {}
29
148
 
30
- export const CheckSelectBoxRoot = withProvider<HTMLLabelElement, CheckSelectBoxRootProps>(
31
- CheckboxPrimitive.Root,
32
- "root",
149
+ export const CheckSelectBoxTrigger = withContext<HTMLDivElement, CheckSelectBoxTriggerProps>(
150
+ withStateProps(Primitive.div),
151
+ "trigger",
33
152
  );
34
153
 
35
154
  export interface CheckSelectBoxContentProps
@@ -41,20 +160,106 @@ export const CheckSelectBoxContent = withContext<HTMLDivElement, CheckSelectBoxC
41
160
  "content",
42
161
  );
43
162
 
163
+ export interface CheckSelectBoxBodyProps
164
+ extends PrimitiveProps,
165
+ React.HTMLAttributes<HTMLDivElement> {}
166
+
167
+ export const CheckSelectBoxBody = withContext<HTMLDivElement, CheckSelectBoxBodyProps>(
168
+ withStateProps(Primitive.div),
169
+ "body",
170
+ );
171
+
44
172
  export interface CheckSelectBoxLabelProps
45
173
  extends PrimitiveProps,
46
- React.HTMLAttributes<HTMLSpanElement> {}
174
+ React.HTMLAttributes<HTMLDivElement> {}
47
175
 
48
- export const CheckSelectBoxLabel = withContext<HTMLSpanElement, CheckSelectBoxLabelProps>(
176
+ export const CheckSelectBoxLabel = withContext<HTMLDivElement, CheckSelectBoxLabelProps>(
49
177
  withStateProps(Primitive.div),
50
178
  "label",
51
179
  );
52
180
 
53
181
  export interface CheckSelectBoxDescriptionProps
54
182
  extends PrimitiveProps,
55
- React.HTMLAttributes<HTMLSpanElement> {}
183
+ React.HTMLAttributes<HTMLDivElement> {}
56
184
 
57
185
  export const CheckSelectBoxDescription = withContext<
58
- HTMLSpanElement,
186
+ HTMLDivElement,
59
187
  CheckSelectBoxDescriptionProps
60
188
  >(withStateProps(Primitive.div), "description");
189
+
190
+ const { withProvider: withCheckmarkProvider, withContext: withCheckmarkContext } =
191
+ createSlotRecipeContext(selectBoxCheckmark);
192
+ const withCheckmarkStateProps = createWithStateProps([useCheckboxContext]);
193
+
194
+ export interface CheckSelectBoxCheckmarkControlProps
195
+ extends SelectBoxCheckmarkVariantProps,
196
+ CheckboxPrimitive.ControlProps {}
197
+
198
+ export const CheckSelectBoxCheckmarkControl = withCheckmarkProvider<
199
+ HTMLDivElement,
200
+ CheckSelectBoxCheckmarkControlProps
201
+ >(CheckboxPrimitive.Control, "root");
202
+
203
+ export interface CheckSelectBoxCheckmarkIconProps extends InternalIconProps {}
204
+
205
+ export const CheckSelectBoxCheckmarkIcon = withCheckmarkContext<
206
+ SVGSVGElement,
207
+ CheckSelectBoxCheckmarkIconProps
208
+ >(withCheckmarkStateProps(InternalIcon), "icon");
209
+
210
+ export interface CheckSelectBoxHiddenInputProps extends CheckboxPrimitive.HiddenInputProps {}
211
+
212
+ export const CheckSelectBoxHiddenInput = forwardRef<
213
+ HTMLInputElement,
214
+ CheckSelectBoxHiddenInputProps
215
+ >((props, ref) => {
216
+ // when footerVisibility !== "when-selected", this context is automatically unavailable since it's not wrapped in CollapsibleProvider
217
+ const collapsibleContext = useCollapsibleContext({ strict: false });
218
+ const footerContext = useContext(FooterContext);
219
+
220
+ const triggerAriaProps = footerContext?.isFooterRendered
221
+ ? collapsibleContext?.triggerAriaProps
222
+ : undefined;
223
+
224
+ return <CheckboxPrimitive.HiddenInput ref={ref} {...triggerAriaProps} {...props} />;
225
+ });
226
+ CheckSelectBoxHiddenInput.displayName = "CheckSelectBoxHiddenInput";
227
+
228
+ export interface CheckSelectBoxFooterProps
229
+ extends PrimitiveProps,
230
+ React.HTMLAttributes<HTMLDivElement> {}
231
+
232
+ export const CheckSelectBoxFooter = forwardRef<HTMLDivElement, CheckSelectBoxFooterProps>(
233
+ ({ className, children, ...props }, ref) => {
234
+ const classNames = useClassNames();
235
+ const { stateProps } = useCheckboxContext();
236
+ const collapsibleContext = useCollapsibleContext({ strict: false });
237
+ const footerContext = useContext(FooterContext);
238
+ const composedRef = composeRefs(ref, footerContext?.footerRef ?? null);
239
+
240
+ if (collapsibleContext) {
241
+ return (
242
+ <Collapsible.Content
243
+ ref={composedRef}
244
+ className={clsx(classNames.footer, className)}
245
+ {...stateProps}
246
+ {...props}
247
+ >
248
+ {children}
249
+ </Collapsible.Content>
250
+ );
251
+ }
252
+
253
+ return (
254
+ <Primitive.div
255
+ ref={composedRef}
256
+ className={clsx(classNames.footer, className)}
257
+ {...stateProps}
258
+ {...props}
259
+ >
260
+ {children}
261
+ </Primitive.div>
262
+ );
263
+ },
264
+ );
265
+ CheckSelectBoxFooter.displayName = "CheckSelectBoxFooter";
@@ -1,12 +1,20 @@
1
1
  export {
2
+ RadioSelectBoxBody as Body,
2
3
  RadioSelectBoxContent as Content,
3
4
  RadioSelectBoxDescription as Description,
5
+ RadioSelectBoxFooter as Footer,
6
+ RadioSelectBoxGroup as Group,
7
+ RadioSelectBoxHiddenInput as HiddenInput,
4
8
  RadioSelectBoxItem as Item,
5
9
  RadioSelectBoxLabel as Label,
6
- RadioSelectBoxRoot as Root,
10
+ RadioSelectBoxTrigger as Trigger,
11
+ type RadioSelectBoxBodyProps as BodyProps,
7
12
  type RadioSelectBoxContentProps as ContentProps,
8
13
  type RadioSelectBoxDescriptionProps as DescriptionProps,
14
+ type RadioSelectBoxFooterProps as FooterProps,
15
+ type RadioSelectBoxGroupProps as GroupProps,
16
+ type RadioSelectBoxHiddenInputProps as HiddenInputProps,
9
17
  type RadioSelectBoxItemProps as ItemProps,
10
18
  type RadioSelectBoxLabelProps as LabelProps,
11
- type RadioSelectBoxRootProps as RootProps,
19
+ type RadioSelectBoxTriggerProps as TriggerProps,
12
20
  } from "./RadioSelectBox";
@@ -1,29 +1,153 @@
1
- import { selectBox } from "@seed-design/css/recipes/select-box";
2
- import { selectBoxGroup } from "@seed-design/css/recipes/select-box-group";
1
+ import { composeRefs } from "@radix-ui/react-compose-refs";
2
+ import { selectBox, type SelectBoxVariantProps } from "@seed-design/css/recipes/select-box";
3
+ import {
4
+ selectBoxGroup,
5
+ type SelectBoxGroupVariantProps,
6
+ } from "@seed-design/css/recipes/select-box-group";
7
+ import {
8
+ Collapsible,
9
+ CollapsibleProvider,
10
+ useCollapsible,
11
+ useCollapsibleContext,
12
+ } from "@seed-design/react-collapsible";
3
13
  import { Primitive, type PrimitiveProps } from "@seed-design/react-primitive";
4
14
  import {
5
15
  RadioGroup as RadioGroupPrimitive,
6
16
  useRadioGroupItemContext,
7
17
  } from "@seed-design/react-radio-group";
8
- import { createRecipeContext } from "../../utils/createRecipeContext";
18
+ import {
19
+ createContext,
20
+ forwardRef,
21
+ useCallback,
22
+ useContext,
23
+ useState,
24
+ type PropsWithChildren,
25
+ } from "react";
9
26
  import { createSlotRecipeContext } from "../../utils/createSlotRecipeContext";
10
27
  import { createWithStateProps } from "../../utils/createWithStateProps";
28
+ import clsx from "clsx";
29
+
30
+ const { PropsProvider, ClassNamesProvider, withContext, useProps, useClassNames } =
31
+ createSlotRecipeContext(selectBox);
11
32
 
12
- const { withContext: withGroupContext } = createRecipeContext(selectBoxGroup);
13
- const { withContext, withProvider } = createSlotRecipeContext(selectBox);
14
33
  const withStateProps = createWithStateProps([useRadioGroupItemContext]);
15
34
 
16
- export interface RadioSelectBoxRootProps extends RadioGroupPrimitive.RootProps {}
35
+ const FooterContext = createContext<{
36
+ isFooterRendered: boolean;
37
+ footerRef: (node: HTMLDivElement | null) => void;
38
+ footerVisibility: Exclude<NonNullable<RadioSelectBoxItemProps["footerVisibility"]>, "always">;
39
+ } | null>(null);
40
+
41
+ export interface RadioSelectBoxGroupProps
42
+ extends SelectBoxGroupVariantProps,
43
+ PrimitiveProps,
44
+ React.HTMLAttributes<HTMLDivElement> {
45
+ /**
46
+ * Number of columns in the grid layout. When bigger than 1, child `RadioSelectBoxItem` will have a default layout of "vertical".
47
+ * @default 1
48
+ */
49
+ columns?: number;
50
+ }
17
51
 
18
- export const RadioSelectBoxRoot = withGroupContext<HTMLDivElement, RadioSelectBoxRootProps>(
19
- RadioGroupPrimitive.Root,
52
+ export const RadioSelectBoxGroup = forwardRef<HTMLDivElement, RadioSelectBoxGroupProps>(
53
+ ({ columns = 1, className, style, ...props }, ref) => {
54
+ const [variantProps, otherProps] = selectBoxGroup.splitVariantProps(props);
55
+ const recipeClassName = selectBoxGroup(variantProps);
56
+ const layout = columns === 1 ? "horizontal" : "vertical";
57
+
58
+ return (
59
+ <PropsProvider value={{ layout }}>
60
+ <Primitive.div
61
+ ref={ref}
62
+ data-columns={columns}
63
+ className={clsx(recipeClassName, className)}
64
+ style={
65
+ {
66
+ ...style,
67
+ "--seed-select-box-group--columns": columns,
68
+ } as React.CSSProperties
69
+ }
70
+ {...otherProps}
71
+ />
72
+ </PropsProvider>
73
+ );
74
+ },
20
75
  );
21
76
 
22
- export interface RadioSelectBoxItemProps extends RadioGroupPrimitive.ItemProps {}
77
+ function FooterVisibilityProvider({
78
+ children,
79
+ footerVisibility,
80
+ }: PropsWithChildren<{
81
+ footerVisibility: Exclude<NonNullable<RadioSelectBoxItemProps["footerVisibility"]>, "always">;
82
+ }>) {
83
+ const { checked } = useRadioGroupItemContext();
84
+
85
+ const collapsible = useCollapsible({
86
+ open: {
87
+ "when-selected": checked,
88
+ "when-not-selected": !checked,
89
+ }[footerVisibility],
90
+ });
91
+
92
+ const [isFooterRendered, setIsFooterRendered] = useState(false);
93
+ const footerRef = useCallback((node: HTMLDivElement | null) => {
94
+ setIsFooterRendered(!!node);
95
+ }, []);
96
+
97
+ return (
98
+ <CollapsibleProvider value={collapsible}>
99
+ <FooterContext.Provider value={{ isFooterRendered, footerRef, footerVisibility }}>
100
+ {children}
101
+ </FooterContext.Provider>
102
+ </CollapsibleProvider>
103
+ );
104
+ }
105
+
106
+ export interface RadioSelectBoxItemProps
107
+ extends SelectBoxVariantProps,
108
+ RadioGroupPrimitive.ItemProps {
109
+ /**
110
+ * Controls when the footer is visible.
111
+ * @default "when-selected"
112
+ */
113
+ footerVisibility?: "when-selected" | "when-not-selected" | "always";
114
+ }
23
115
 
24
- export const RadioSelectBoxItem = withProvider<HTMLLabelElement, RadioSelectBoxItemProps>(
25
- RadioGroupPrimitive.Item,
26
- "root",
116
+ export const RadioSelectBoxItem = forwardRef<HTMLLabelElement, RadioSelectBoxItemProps>(
117
+ ({ footerVisibility = "when-selected", className, children, ...props }, ref) => {
118
+ const [variantProps, otherProps] = selectBox.splitVariantProps(props);
119
+ const classNames = selectBox({
120
+ ...useProps(),
121
+ ...variantProps,
122
+ });
123
+
124
+ return (
125
+ <ClassNamesProvider value={classNames}>
126
+ <RadioGroupPrimitive.Item
127
+ ref={ref}
128
+ className={clsx(classNames.root, className)}
129
+ {...otherProps}
130
+ >
131
+ {footerVisibility === "always" ? (
132
+ children
133
+ ) : (
134
+ <FooterVisibilityProvider footerVisibility={footerVisibility}>
135
+ {children}
136
+ </FooterVisibilityProvider>
137
+ )}
138
+ </RadioGroupPrimitive.Item>
139
+ </ClassNamesProvider>
140
+ );
141
+ },
142
+ );
143
+
144
+ export interface RadioSelectBoxTriggerProps
145
+ extends PrimitiveProps,
146
+ React.HTMLAttributes<HTMLDivElement> {}
147
+
148
+ export const RadioSelectBoxTrigger = withContext<HTMLDivElement, RadioSelectBoxTriggerProps>(
149
+ withStateProps(Primitive.div),
150
+ "trigger",
27
151
  );
28
152
 
29
153
  export interface RadioSelectBoxContentProps
@@ -35,20 +159,90 @@ export const RadioSelectBoxContent = withContext<HTMLDivElement, RadioSelectBoxC
35
159
  "content",
36
160
  );
37
161
 
162
+ export interface RadioSelectBoxBodyProps
163
+ extends PrimitiveProps,
164
+ React.HTMLAttributes<HTMLDivElement> {}
165
+
166
+ export const RadioSelectBoxBody = withContext<HTMLDivElement, RadioSelectBoxBodyProps>(
167
+ withStateProps(Primitive.div),
168
+ "body",
169
+ );
170
+
38
171
  export interface RadioSelectBoxLabelProps
39
172
  extends PrimitiveProps,
40
- React.HTMLAttributes<HTMLSpanElement> {}
173
+ React.HTMLAttributes<HTMLDivElement> {}
41
174
 
42
- export const RadioSelectBoxLabel = withContext<HTMLSpanElement, RadioSelectBoxLabelProps>(
175
+ export const RadioSelectBoxLabel = withContext<HTMLDivElement, RadioSelectBoxLabelProps>(
43
176
  withStateProps(Primitive.div),
44
177
  "label",
45
178
  );
46
179
 
47
180
  export interface RadioSelectBoxDescriptionProps
48
181
  extends PrimitiveProps,
49
- React.HTMLAttributes<HTMLSpanElement> {}
182
+ React.HTMLAttributes<HTMLDivElement> {}
50
183
 
51
184
  export const RadioSelectBoxDescription = withContext<
52
- HTMLSpanElement,
185
+ HTMLDivElement,
53
186
  RadioSelectBoxDescriptionProps
54
187
  >(withStateProps(Primitive.div), "description");
188
+
189
+ export interface RadioSelectBoxHiddenInputProps extends RadioGroupPrimitive.ItemHiddenInputProps {}
190
+
191
+ export const RadioSelectBoxHiddenInput = forwardRef<
192
+ HTMLInputElement,
193
+ RadioSelectBoxHiddenInputProps
194
+ >((props, ref) => {
195
+ // when footerVisibility !== "when-selected", this context is automatically unavailable since it's not wrapped in CollapsibleProvider
196
+
197
+ // NOTE: aria-expanded on role="radio" is not officially supported. See: https://github.com/w3c/aria/issues/1404
198
+ // but it helps some screen readers to announce the expanded/collapsed state of the footer.
199
+ // gov.uk applies aria-expanded on the radio input as well. See: https://design-system.service.gov.uk/components/radios/#conditionally-revealing-a-related-question
200
+ const collapsibleContext = useCollapsibleContext({ strict: false });
201
+ const footerContext = useContext(FooterContext);
202
+
203
+ const triggerAriaProps = footerContext?.isFooterRendered
204
+ ? collapsibleContext?.triggerAriaProps
205
+ : undefined;
206
+
207
+ return <RadioGroupPrimitive.ItemHiddenInput ref={ref} {...triggerAriaProps} {...props} />;
208
+ });
209
+ RadioSelectBoxHiddenInput.displayName = "RadioSelectBoxHiddenInput";
210
+
211
+ export interface RadioSelectBoxFooterProps
212
+ extends PrimitiveProps,
213
+ React.HTMLAttributes<HTMLDivElement> {}
214
+
215
+ export const RadioSelectBoxFooter = forwardRef<HTMLDivElement, RadioSelectBoxFooterProps>(
216
+ ({ className, children, ...props }, ref) => {
217
+ const classNames = useClassNames();
218
+ const { stateProps } = useRadioGroupItemContext();
219
+ const collapsibleContext = useCollapsibleContext({ strict: false });
220
+ const footerContext = useContext(FooterContext);
221
+ const composedRef = composeRefs(ref, footerContext?.footerRef ?? null);
222
+
223
+ if (collapsibleContext) {
224
+ return (
225
+ <Collapsible.Content
226
+ ref={composedRef}
227
+ className={clsx(classNames.footer, className)}
228
+ {...stateProps}
229
+ {...props}
230
+ >
231
+ {children}
232
+ </Collapsible.Content>
233
+ );
234
+ }
235
+
236
+ return (
237
+ <Primitive.div
238
+ ref={composedRef}
239
+ className={clsx(classNames.footer, className)}
240
+ {...stateProps}
241
+ {...props}
242
+ >
243
+ {children}
244
+ </Primitive.div>
245
+ );
246
+ },
247
+ );
248
+ RadioSelectBoxFooter.displayName = "RadioSelectBoxFooter";
@@ -1,27 +1,47 @@
1
1
  export {
2
+ CheckSelectBoxBody,
3
+ CheckSelectBoxCheckmarkControl,
4
+ CheckSelectBoxCheckmarkIcon,
2
5
  CheckSelectBoxContent,
3
6
  CheckSelectBoxDescription,
7
+ CheckSelectBoxFooter,
4
8
  CheckSelectBoxGroup,
9
+ CheckSelectBoxHiddenInput,
5
10
  CheckSelectBoxLabel,
6
11
  CheckSelectBoxRoot,
12
+ CheckSelectBoxTrigger,
13
+ type CheckSelectBoxBodyProps,
14
+ type CheckSelectBoxCheckmarkControlProps,
15
+ type CheckSelectBoxCheckmarkIconProps,
7
16
  type CheckSelectBoxContentProps,
8
17
  type CheckSelectBoxDescriptionProps,
18
+ type CheckSelectBoxFooterProps,
9
19
  type CheckSelectBoxGroupProps,
20
+ type CheckSelectBoxHiddenInputProps,
10
21
  type CheckSelectBoxLabelProps,
11
22
  type CheckSelectBoxRootProps,
23
+ type CheckSelectBoxTriggerProps,
12
24
  } from "./CheckSelectBox";
13
25
 
14
26
  export {
27
+ RadioSelectBoxBody,
15
28
  RadioSelectBoxContent,
16
29
  RadioSelectBoxDescription,
30
+ RadioSelectBoxFooter,
31
+ RadioSelectBoxGroup,
32
+ RadioSelectBoxHiddenInput,
17
33
  RadioSelectBoxItem,
18
34
  RadioSelectBoxLabel,
19
- RadioSelectBoxRoot,
35
+ RadioSelectBoxTrigger,
36
+ type RadioSelectBoxBodyProps,
20
37
  type RadioSelectBoxContentProps,
21
38
  type RadioSelectBoxDescriptionProps,
39
+ type RadioSelectBoxFooterProps,
40
+ type RadioSelectBoxGroupProps,
41
+ type RadioSelectBoxHiddenInputProps,
22
42
  type RadioSelectBoxItemProps,
23
43
  type RadioSelectBoxLabelProps,
24
- type RadioSelectBoxRootProps,
44
+ type RadioSelectBoxTriggerProps,
25
45
  } from "./RadioSelectBox";
26
46
 
27
47
  export * as CheckSelectBox from "./CheckSelectBox.namespace";
@@ -1,6 +1,6 @@
1
1
  import { Switch as SwitchPrimitive, useSwitchContext } from "@seed-design/react-switch";
2
2
  import { switchStyle, type SwitchVariantProps } from "@seed-design/css/recipes/switch";
3
- import { switchMark, type SwitchMarkVariantProps } from "@seed-design/css/recipes/switch-mark";
3
+ import { switchmark, type SwitchmarkVariantProps } from "@seed-design/css/recipes/switchmark";
4
4
  import { createSlotRecipeContext } from "../../utils/createSlotRecipeContext";
5
5
  import { Primitive, type PrimitiveProps } from "@seed-design/react-primitive";
6
6
  import { createWithStateProps } from "../../utils/createWithStateProps";
@@ -13,7 +13,7 @@ const {
13
13
  withContext: withControlContext,
14
14
  PropsProvider: ControlPropsProvider,
15
15
  withProvider: withControlProvider,
16
- } = createSlotRecipeContext(switchMark);
16
+ } = createSlotRecipeContext(switchmark);
17
17
  const withStateProps = createWithStateProps([useSwitchContext]);
18
18
 
19
19
  ////////////////////////////////////////////////////////////////////////////////////
@@ -25,7 +25,7 @@ type SwitchVariantDeprecatedSizeProps = "small" | "medium";
25
25
 
26
26
  export interface SwitchRootProps
27
27
  extends Omit<SwitchVariantProps, "size">,
28
- Omit<SwitchMarkVariantProps, "size">,
28
+ Omit<SwitchmarkVariantProps, "size">,
29
29
  SwitchPrimitive.RootProps {
30
30
  size?: SwitchVariantProps["size"] | SwitchVariantDeprecatedSizeProps;
31
31
  }
@@ -41,20 +41,20 @@ export const SwitchRoot = React.forwardRef<HTMLLabelElement, SwitchRootProps>(
41
41
  );
42
42
  }
43
43
 
44
- const [{ switch: switchVariantProps, switchMark: switchMarkVariantProps }, otherProps] =
44
+ const [{ switch: switchVariantProps, switchmark: switchmarkVariantProps }, otherProps] =
45
45
  splitMultipleVariantsProps(
46
46
  {
47
47
  ...props,
48
48
  // TODO: replace this mapping completely
49
49
  size: props.size === "small" ? "16" : props.size === "medium" ? "32" : props.size,
50
50
  },
51
- { switchMark, switch: switchStyle },
51
+ { switchmark, switch: switchStyle },
52
52
  );
53
53
 
54
54
  const classNames = switchStyle(switchVariantProps);
55
55
 
56
56
  return (
57
- <ControlPropsProvider value={switchMarkVariantProps}>
57
+ <ControlPropsProvider value={switchmarkVariantProps}>
58
58
  <ClassNamesProvider value={classNames}>
59
59
  <SwitchPrimitive.Root
60
60
  ref={ref}
@@ -70,7 +70,7 @@ SwitchRoot.displayName = "SwitchRoot";
70
70
 
71
71
  ////////////////////////////////////////////////////////////////////////////////////
72
72
 
73
- export interface SwitchControlProps extends SwitchMarkVariantProps, SwitchPrimitive.ControlProps {}
73
+ export interface SwitchControlProps extends SwitchmarkVariantProps, SwitchPrimitive.ControlProps {}
74
74
 
75
75
  export const SwitchControl = withControlProvider<HTMLDivElement, SwitchControlProps>(
76
76
  SwitchPrimitive.Control,
@@ -1,6 +1,8 @@
1
1
  export {
2
2
  TagGroupRoot as Root,
3
3
  TagGroupItem as Item,
4
+ TagGroupItemLabel as ItemLabel,
4
5
  type TagGroupRootProps as RootProps,
5
6
  type TagGroupItemProps as ItemProps,
7
+ type TagGroupItemLabelProps as ItemLabelProps,
6
8
  } from "./TagGroup";