Skip to content

Commit

Permalink
Enhance VanillaRenderer customizable class names
Browse files Browse the repository at this point in the history
* Change order of classnames for layouts
* Allow customization of the validation class
* Add class to validation element even if no error occurs
* Make validation error class customizable
  • Loading branch information
TheZoker authored Jan 22, 2021
1 parent 569b23b commit 64859ec
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 17 deletions.
4 changes: 4 additions & 0 deletions packages/vanilla/Styles.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
- array.table.table → id for the table
- array.table.label → id for the label in the header
- array.table.button → id for the add button
- array.table.validation → id for the validation field
- array.table.validation.error → id for the validation error field
- array.validation.error → id for the validation column if activated
### GroupRenderer
#### Hardcoded ClassNames
Expand All @@ -49,6 +51,8 @@
#### Ids
- control → id for the whole control
- control.label → id for the label of control
- control.validation → id for the validation of control
- control.validation.error → id for the validation error of control
- input.description → id for the description of control

## Example of styling id contributions
Expand Down
18 changes: 12 additions & 6 deletions packages/vanilla/src/complex/TableArrayControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class TableArrayControl extends React.Component<ArrayControlProps & VanillaRende
const tableClass = getStyleAsClassName('array.table.table');
const labelClass = getStyleAsClassName('array.table.label');
const buttonClass = getStyleAsClassName('array.table.button');
const validationClass = getStyleAsClassName('array.table.validation');
const controlClass = [
getStyleAsClassName('array.table'),
convertToValidClassName(controlElement.scope)
Expand All @@ -96,7 +97,9 @@ class TableArrayControl extends React.Component<ArrayControlProps & VanillaRende
});
const labelObject = createLabelDescriptionFrom(controlElement, schema);
const isValid = errors.length === 0;
const divClassNames = 'validation' + (isValid ? '' : ' validation_error');
const divClassNames = [validationClass]
.concat(isValid ? '' : getStyleAsClassName('array.table.validation.error'))
.join(' ');
const labelText = isPlainLabel(label) ? label : label.default;

return (
Expand Down Expand Up @@ -145,6 +148,12 @@ class TableArrayControl extends React.Component<ArrayControlProps & VanillaRende
error.dataPath.startsWith(childPath)
);

const validationClassName = getStyleAsClassName('array.validation');
const errorValidationClassName = getStyleAsClassName('array.validation.error');
const errorClassNames = errorsPerEntry ?
[validationClassName].concat(errorValidationClassName).join(' ') :
validationClassName;

return (
<tr key={childPath}>
{schema.properties ? (
Expand Down Expand Up @@ -186,15 +195,12 @@ class TableArrayControl extends React.Component<ArrayControlProps & VanillaRende
)}
<td>
{errorsPerEntry ? (
<span
className={getStyleAsClassName(
'array.validation.error'
)}
<span className={errorClassNames}
>
{join(errorsPerEntry.map(e => e.message), ' and ')}
</span>
) : (
<span>OK</span>
<span className={errorClassNames}>OK</span>
)}
</td>
<td>
Expand Down
7 changes: 4 additions & 3 deletions packages/vanilla/src/controls/InputControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@ export class InputControl extends Control<
} = this.props;

const isValid = errors.length === 0;
const divClassNames = `validation ${
isValid ? classNames.description : 'validation_error'
}`;

const divClassNames = [classNames.validation]
.concat(isValid ? classNames.description : classNames.validationError)
.join(' ');

const appliedUiSchemaOptions = merge({}, config, uischema.options);
const showDescription = !isDescriptionHidden(
Expand Down
4 changes: 2 additions & 2 deletions packages/vanilla/src/layouts/GroupLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ export const GroupLayoutRenderer: FunctionComponent<RendererProps & VanillaRende
const group = uischema as GroupLayout;
const elementsSize = group.elements ? group.elements.length : 0;
const classNames = getStyleAsClassName('group.layout');
const childClassNames = getStyle('group.layout.item', elementsSize)
.concat(['group-layout-item'])
const childClassNames = ['group-layout-item']
.concat(getStyle('group.layout.item', elementsSize))
.join(' ');

return (
Expand Down
4 changes: 2 additions & 2 deletions packages/vanilla/src/layouts/HorizontalLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ const HorizontalLayoutRenderer: FunctionComponent<RendererProps & VanillaRendere
const horizontalLayout = uischema as HorizontalLayout;
const elementsSize = horizontalLayout.elements ? horizontalLayout.elements.length : 0;
const layoutClassName = getStyleAsClassName('horizontal.layout');
const childClassNames = getStyle('horizontal.layout.item', elementsSize)
.concat(['horizontal-layout-item'])
const childClassNames = ['horizontal-layout-item']
.concat(getStyle('horizontal.layout.item', elementsSize))
.join(' ');

return (
Expand Down
4 changes: 2 additions & 2 deletions packages/vanilla/src/layouts/VerticalLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ export const VerticalLayoutRenderer: FunctionComponent<RendererProps & VanillaRe
const verticalLayout = uischema as VerticalLayout;
const elementsSize = verticalLayout.elements ? verticalLayout.elements.length : 0;
const layoutClassName = getStyleAsClassName('vertical.layout');
const childClassNames = getStyle('vertical.layout.item', elementsSize)
.concat(['vertical-layout-item'])
const childClassNames = ['vertical-layout-item']
.concat(getStyle('vertical.layout.item', elementsSize))
.join(' ');

return (
Expand Down
12 changes: 12 additions & 0 deletions packages/vanilla/src/styles/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ export const vanillaStyles: StyleDef[] = [
name: 'control.select',
classNames: ['select']
},
{
name: 'control.validation.error',
classNames: ['validation_error']
},
{
name: 'control.validation',
classNames: ['validation']
Expand Down Expand Up @@ -97,6 +101,14 @@ export const vanillaStyles: StyleDef[] = [
name: 'vertical.layout',
classNames: ['vertical-layout']
},
{
name: 'array.table.validation.error',
classNames: ['validation_error']
},
{
name: 'array.table.validation',
classNames: ['validation']
},
{
name: 'array.table',
classNames: ['array-table-layout', 'control']
Expand Down
12 changes: 10 additions & 2 deletions packages/vanilla/src/util/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ export const addVanillaControlProps = <P extends StatePropsOfControl>(
}
const labelClass = getStyleAsClassName(state)('control.label');
const descriptionClassName = getStyleAsClassName(state)('input.description');
const validationClassName = getStyleAsClassName(state)('control.validation');
const validationErrorClassName = getStyleAsClassName(state)('control.validation.error');
const inputClassName = ['validate'].concat(isValid ? 'valid' : 'invalid');

return {
Expand All @@ -81,7 +83,9 @@ export const addVanillaControlProps = <P extends StatePropsOfControl>(
wrapper: classNames.join(' '),
input: inputClassName.join(' '),
label: labelClass,
description: descriptionClassName
description: descriptionClassName,
validation: validationClassName,
validationError: validationErrorClassName
}
};
};
Expand All @@ -103,6 +107,8 @@ export const withVanillaControlProps = (Component: ComponentType<any>) => (props
const isValid = isEmpty(props.errors);
const labelClass = findStyleAsClassName(contextStyles)('control.label');
const descriptionClassName = findStyleAsClassName(contextStyles)('input.description');
const validationClassName = findStyleAsClassName(contextStyles)('control.validation');
const validationErrorClassName = findStyleAsClassName(contextStyles)('control.validation.error');
const inputClassName = ['validate'].concat(isValid ? 'valid' : 'invalid');
return (
<Component
Expand All @@ -113,7 +119,9 @@ export const withVanillaControlProps = (Component: ComponentType<any>) => (props
wrapper: classNames.join(' '),
input: inputClassName.join(' '),
label: labelClass,
description: descriptionClassName
description: descriptionClassName,
validation: validationClassName,
validationError: validationErrorClassName
}}
/>
);
Expand Down
28 changes: 28 additions & 0 deletions packages/vanilla/test/renderers/InputControl.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import BooleanCell, { booleanCellTester } from '../../src/cells/BooleanCell';
import TextCell, { textCellTester } from '../../src/cells/TextCell';
import DateCell, { dateCellTester } from '../../src/cells/DateCell';
import { initJsonFormsVanillaStore } from '../vanillaStore';
import { JsonFormsStyleContext } from '../../src/styles';

Enzyme.configure({ adapter: new Adapter() });

Expand Down Expand Up @@ -308,6 +309,33 @@ describe('Input control', () => {
expect(validation.text()).toBe('');
});

test('custom validation class', () => {
const store = initJsonFormsVanillaStore({
data: fixture.data,
schema: fixture.schema,
uischema: fixture.uischema,
renderers: [{ tester: inputControlTester, renderer: InputControl }],
cells: [{ tester: booleanCellTester, cell: BooleanCell }]
});
const styleContextValue = { styles: [
{
name: 'control.validation',
classNames: ['custom-validation']
},
]};
wrapper = mount(
<Provider store={store}>
<JsonFormsReduxContext>
<JsonFormsStyleContext.Provider value={styleContextValue}>
<JsonFormsDispatch />
</JsonFormsStyleContext.Provider>
</JsonFormsReduxContext>
</Provider>
);
const validation = wrapper.find('.custom-validation');
expect(validation.exists()).toBeTruthy();
});

test('reset validation message', () => {
const store = initJsonFormsVanillaStore({
data: fixture.data,
Expand Down

0 comments on commit 64859ec

Please sign in to comment.