diff --git a/packages/examples/src/examples/enum-multi-with-label-and-desc.ts b/packages/examples/src/examples/enum-multi-with-label-and-desc.ts new file mode 100644 index 000000000..f87417545 --- /dev/null +++ b/packages/examples/src/examples/enum-multi-with-label-and-desc.ts @@ -0,0 +1,86 @@ +/* + The MIT License + + Copyright (c) 2017-2020 EclipseSource Munich + https://github.com/eclipsesource/jsonforms + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ +import { registerExamples } from '../register'; + +export const schema = { + type: 'object', + properties: { + oneOfMultiEnum: { + type: 'array', + uniqueItems: true, + description: 'Description', + items: { + oneOf: [ + { const: 'foo', title: 'My Foo' }, + { const: 'bar', title: 'My Bar' }, + { const: 'foobar', title: 'My FooBar' }, + ], + }, + }, + multiEnum: { + type: 'array', + uniqueItems: true, + description: 'Description', + items: { + type: 'string', + enum: ['foo', 'bar', 'foobar'], + }, + }, + }, +}; + +export const uischema = { + type: 'VerticalLayout', + elements: [ + { + type: 'Control', + scope: '#/properties/oneOfMultiEnum', + label: 'Form Label', + options: { + showUnfocusedDescription: true, + }, + }, + { + type: 'Control', + scope: '#/properties/multiEnum', + label: 'Form Label', + options: { + showUnfocusedDescription: true, + }, + }, + ], +}; + +export const data = { oneOfMultiEnum: ['foo'], multiEnum: ['bar'] }; + +registerExamples([ + { + name: 'multi-enum-with-label-and-desc', + label: 'Enum - Multi selection with label and desc', + data, + schema, + uischema, + }, +]); diff --git a/packages/examples/src/index.ts b/packages/examples/src/index.ts index f4c5ed51b..33486d225 100644 --- a/packages/examples/src/index.ts +++ b/packages/examples/src/index.ts @@ -71,6 +71,7 @@ import * as readonly from './examples/readonly'; import * as listWithDetailPrimitives from './examples/list-with-detail-primitives'; import * as conditionalSchemaComposition from './examples/conditional-schema-compositions'; import * as additionalErrors from './examples/additional-errors'; +import * as multiEnumWithLabelAndDesc from './examples/enum-multi-with-label-and-desc'; export * from './register'; export * from './example'; @@ -120,6 +121,7 @@ export { enumExample, radioGroupExample, multiEnum, + multiEnumWithLabelAndDesc, enumInArray, readonly, listWithDetailPrimitives, diff --git a/packages/material-renderers/src/complex/MaterialEnumArrayRenderer.tsx b/packages/material-renderers/src/complex/MaterialEnumArrayRenderer.tsx index 9ed5916d9..9da40758f 100644 --- a/packages/material-renderers/src/complex/MaterialEnumArrayRenderer.tsx +++ b/packages/material-renderers/src/complex/MaterialEnumArrayRenderer.tsx @@ -3,6 +3,7 @@ import { ControlProps, DispatchPropsOfMultiEnumControl, hasType, + isDescriptionHidden, JsonSchema, OwnPropsOfEnum, Paths, @@ -11,6 +12,7 @@ import { resolveSchema, schemaMatches, schemaSubPathMatches, + showAsRequired, uiTypeIs, } from '@jsonforms/core'; @@ -21,15 +23,23 @@ import { FormControlLabel, FormGroup, FormHelperText, + FormLabel, Hidden, } from '@mui/material'; import isEmpty from 'lodash/isEmpty'; import React from 'react'; +import merge from 'lodash/merge'; +import { useFocus } from '../util'; export const MaterialEnumArrayRenderer = ({ + config, + id, schema, visible, errors, + description, + label, + required, path, options, data, @@ -38,9 +48,34 @@ export const MaterialEnumArrayRenderer = ({ handleChange: _handleChange, ...otherProps }: ControlProps & OwnPropsOfEnum & DispatchPropsOfMultiEnumControl) => { + const [focused, onFocus, onBlur] = useFocus(); + const isValid = errors.length === 0; + const appliedUiSchemaOptions = merge({}, config, otherProps.uischema.options); + const showDescription = !isDescriptionHidden( + visible, + description, + focused, + appliedUiSchemaOptions.showUnfocusedDescription + ); + return ( - + + + {label} + {options.map((option: any, index: number) => { const optionPath = Paths.compose(path, `${index}`); @@ -49,10 +84,11 @@ export const MaterialEnumArrayRenderer = ({ : undefined; return ( - {errors} + + {!isValid ? errors : showDescription ? description : null} + ); diff --git a/packages/material-renderers/src/controls/MaterialRadioGroup.tsx b/packages/material-renderers/src/controls/MaterialRadioGroup.tsx index 2639f0ee2..be2a9aece 100644 --- a/packages/material-renderers/src/controls/MaterialRadioGroup.tsx +++ b/packages/material-renderers/src/controls/MaterialRadioGroup.tsx @@ -45,7 +45,6 @@ export const MaterialRadioGroup = (props: ControlProps & OwnPropsOfEnum) => { const [focused, onFocus, onBlur] = useFocus(); const { config, - id, label, required, description, @@ -69,15 +68,14 @@ export const MaterialRadioGroup = (props: ControlProps & OwnPropsOfEnum) => { return ( { { done(); }, 50); }); + + test('oneOf items - renders label for the form group', () => { + wrapper = mount( + + ); + expect(wrapper.find(FormLabel).text()).toBe('Label'); + }); + + test('enum items - renders label for the form group', () => { + wrapper = mount( + + ); + expect(wrapper.find(FormLabel).text()).toBe('Label'); + }); + + test('oneOf items - renders description for the form group', () => { + wrapper = mount( + + ); + expect(wrapper.find(FormHelperText).text()).toBe('Description'); + }); + + test('enum items - renders description for the form group', () => { + wrapper = mount( + + ); + expect(wrapper.find(FormHelperText).text()).toBe('Description'); + }); });