@@ -18,6 +18,11 @@ import {
1818 schemaRequiresTrueValue ,
1919 descriptionId ,
2020 ariaDescribedByIds ,
21+ enumOptionsIsSelected ,
22+ enumOptionsSelectValue ,
23+ enumOptionsDeselectValue ,
24+ enumOptionsValueForIndex ,
25+ optionId ,
2126} from "@rjsf/utils"
2227import ReactMarkdown from "react-markdown"
2328import remarkGfm from "remark-gfm"
@@ -250,6 +255,63 @@ const MyCheckboxWidget = (props: WidgetProps) => {
250255 )
251256}
252257
258+ const MyCheckboxesWidget = ( props : WidgetProps ) => {
259+ const {
260+ id,
261+ disabled,
262+ options,
263+ value,
264+ readonly,
265+ onChange,
266+ onBlur,
267+ onFocus,
268+ autofocus = false ,
269+ } = props
270+ const { enumOptions, enumDisabled, emptyValue } = options
271+ const checkboxesValues = Array . isArray ( value ) ? value : [ value ]
272+
273+ return (
274+ < div className = "checkboxes-group" id = { id } >
275+ { Array . isArray ( enumOptions ) &&
276+ enumOptions . map ( ( option , index ) => {
277+ const checked = enumOptionsIsSelected ( option . value , checkboxesValues )
278+ const itemDisabled =
279+ Array . isArray ( enumDisabled ) && enumDisabled . indexOf ( option . value ) !== - 1
280+ const disabledCls = disabled || itemDisabled || readonly ? "disabled" : ""
281+
282+ return (
283+ < label key = { index } className = { `checkboxes-option ${ disabledCls } ` } >
284+ < input
285+ type = "checkbox"
286+ id = { optionId ( id , index ) }
287+ name = { id }
288+ checked = { checked }
289+ value = { String ( index ) }
290+ disabled = { disabled || itemDisabled || readonly }
291+ autoFocus = { autofocus && index === 0 }
292+ onChange = { ( event ) => {
293+ if ( event . target . checked ) {
294+ onChange ( enumOptionsSelectValue ( index , checkboxesValues , enumOptions ) )
295+ } else {
296+ onChange ( enumOptionsDeselectValue ( index , checkboxesValues , enumOptions ) )
297+ }
298+ } }
299+ onBlur = { ( { target : { value : v } } ) =>
300+ onBlur ( id , enumOptionsValueForIndex ( v , enumOptions , emptyValue ) )
301+ }
302+ onFocus = { ( { target : { value : v } } ) =>
303+ onFocus ( id , enumOptionsValueForIndex ( v , enumOptions , emptyValue ) )
304+ }
305+ aria-describedby = { ariaDescribedByIds ( id ) }
306+ />
307+ < span > { option . label } </ span >
308+ </ label >
309+ )
310+ } ) }
311+ </ div >
312+ )
313+ }
314+
253315// create Registry information
254316// templates
255317const myTemplates : Partial < TemplatesType > = {
@@ -282,6 +344,7 @@ const myWidgets: RegistryWidgetsType = {
282344 TextWidget : MyTextWidget ,
283345 EmailWidget : MyEmailWidget ,
284346 CheckboxWidget : MyCheckboxWidget ,
347+ CheckboxesWidget : MyCheckboxesWidget ,
285348}
286349
287350// create the overall theme to use on the other page
0 commit comments