diff --git a/packages/spectrum/README.md b/packages/spectrum/README.md index 5021cce0..b182ed53 100644 --- a/packages/spectrum/README.md +++ b/packages/spectrum/README.md @@ -7,3 +7,18 @@ JSONForms eliminates the tedious task of writing fully-featured forms by hand by # Spectrum Renderers Package !!!! Work in Progress !!! + +# Custom options + +### Custom options for Table Array Control +```js +{ + "type": "Control", + "scope": "#/properties/myArray", + "options": { + "addButtonPosition": "top", // "top" or "bottom" + "addButtonLabel": "Add item", // optional custom label for Add button + "addButtonLabelType": "tooltip" // "tooltip" or "inline" + } +} +``` \ No newline at end of file diff --git a/packages/spectrum/src/complex/SpectrumTableArrayControl.tsx b/packages/spectrum/src/complex/SpectrumTableArrayControl.tsx index 7460c8fa..0a6563f6 100644 --- a/packages/spectrum/src/complex/SpectrumTableArrayControl.tsx +++ b/packages/spectrum/src/complex/SpectrumTableArrayControl.tsx @@ -144,6 +144,17 @@ class SpectrumTableArrayControl extends React.Component< )(schema.properties) : [Items]; + const uioptions: UIOptions = { + addButtonPosition: + uischema.options?.addButtonPosition === 'bottom' ? 'bottom' : 'top', + addButtonLabel: + uischema.options?.addButtonLabel || `Add to ${labelObject.text}`, + addButtonLabelType: + uischema.options?.addButtonLabelType === 'inline' + ? 'inline' + : 'tooltip', + }; + return ( - - - - - Add to {labelObject.text} - + /> + )} @@ -286,9 +294,47 @@ class SpectrumTableArrayControl extends React.Component< )} + + {uioptions.addButtonPosition === 'bottom' && ( + + + + )} ); } } export default withJsonFormsArrayControlProps(SpectrumTableArrayControl); + +function AddButton( + props: Pick & { + onPress: () => void; + } +) { + const { addButtonLabel, addButtonLabelType, onPress } = props; + const button = ( + + + {addButtonLabelType === 'inline' && {addButtonLabel}} + + ); + + return addButtonLabelType === 'tooltip' ? ( + + {button} + {addButtonLabel} + + ) : ( + button + ); +} + +interface UIOptions { + addButtonPosition: 'top' | 'bottom'; + addButtonLabel?: string; + addButtonLabelType: 'tooltip' | 'inline'; +} diff --git a/packages/spectrum/test/renderers/SpectrumTableArrayControl.test.tsx b/packages/spectrum/test/renderers/SpectrumTableArrayControl.test.tsx index 079b2cb8..4e69df27 100644 --- a/packages/spectrum/test/renderers/SpectrumTableArrayControl.test.tsx +++ b/packages/spectrum/test/renderers/SpectrumTableArrayControl.test.tsx @@ -384,6 +384,63 @@ describe('Table array control', () => { ) as HTMLElement; expect(tableView.hidden).toBeFalsy(); }); + + describe('uischema.options.addButtonPosition', () => { + test.each([ + [undefined, 'top'], + ['top', 'top'], + ['bottom', 'bottom'], + ['foobar', 'top'], + ])( + 'when option is %s, render Add button on %s', + (value: string | undefined, expectedPosition: 'top' | 'bottom') => { + const { container } = renderForm( + { + ...fixture.uischema, + options: { addButtonPosition: value }, + }, + fixture.schema, + fixture.data + ); + const tablePosition = container.innerHTML.indexOf('spectrum-Table'); + const addButtonPosition = container.innerHTML.indexOf('add-button'); + if (expectedPosition === 'bottom') { + expect(addButtonPosition).toBeGreaterThan(tablePosition); + } else { + expect(addButtonPosition).toBeLessThan(tablePosition); + } + } + ); + }); + + describe('uischema.options.addButtonLabel', () => { + const uischema = { + ...fixture.uischema, + options: { + addButtonLabelType: 'inline', + }, + }; + test('when option is not set, should render the default label', () => { + const { container } = renderForm(uischema, fixture.schema, fixture.data); + expect(container.querySelector('.add-button').textContent).toBe( + 'Add to Test' + ); + }); + + test('when option is set, should render it', () => { + const label = 'increase the count of items'; + const uischemaWithLabel = { + ...uischema, + options: { ...uischema.options, addButtonLabel: label }, + }; + const { container } = renderForm( + uischemaWithLabel, + fixture.schema, + fixture.data + ); + expect(container.querySelector('.add-button').textContent).toBe(label); + }); + }); }); describe('validations messages', () => {