diff --git a/packages/jsonforms-renderers/src/renderers/LayoutRenderers.test.tsx b/packages/jsonforms-renderers/src/renderers/LayoutRenderers.test.tsx new file mode 100644 index 0000000..7ba3dc4 --- /dev/null +++ b/packages/jsonforms-renderers/src/renderers/LayoutRenderers.test.tsx @@ -0,0 +1,93 @@ +// @vitest-environment jsdom +import { afterEach, describe, expect, it } from 'vitest' +import { cleanup, render, screen } from '@testing-library/react' +import { JsonForms } from '@jsonforms/react' +import { Theme } from '@radix-ui/themes' +import type { JsonSchema, UISchemaElement } from '@jsonforms/core' +import { radixRenderers } from './index' + +afterEach(cleanup) + +const schema: JsonSchema = { + type: 'object', + properties: { + kind: { type: 'string' }, + physical: { type: 'string' }, + salmonella: { type: 'string' }, + }, +} + +const control = (name: string, label: string) => ({ type: 'Control', scope: `#/properties/${name}`, label }) + +// SHOW the element when `kind` is one of kinds. +const showFor = (kinds: string[]) => ({ + effect: 'SHOW', + condition: { scope: '#/properties/kind', schema: { enum: kinds } }, +}) + +function renderForm(uischema: unknown, data: Record) { + render( + + + , + ) +} + +describe('layout rules', () => { + const groups = { + type: 'VerticalLayout', + elements: [ + { + type: 'Group', + label: 'Physical Group', + rule: showFor(['P', 'PS']), + elements: [control('physical', 'Physical No.')], + }, + { + type: 'Group', + label: 'Salmonella Group', + rule: showFor(['S', 'PS']), + elements: [control('salmonella', 'Salmonella No.')], + }, + ], + } + + it('shows only the Group whose SHOW rule matches', () => { + renderForm(groups, { kind: 'P' }) + + expect(screen.getByText('Physical Group')).toBeTruthy() + expect(screen.getByText('Physical No.')).toBeTruthy() + expect(screen.queryByText('Salmonella Group')).toBeNull() + expect(screen.queryByText('Salmonella No.')).toBeNull() + }) + + it('shows every Group whose SHOW rule matches', () => { + renderForm(groups, { kind: 'PS' }) + + expect(screen.getByText('Physical Group')).toBeTruthy() + expect(screen.getByText('Salmonella Group')).toBeTruthy() + }) + + it.each([ + ['VerticalLayout', 'Vertical No.'], + ['HorizontalLayout', 'Horizontal No.'], + ])('applies a HIDE rule to a %s', (type, label) => { + const uischema = { + type: 'VerticalLayout', + elements: [ + { + type, + rule: { effect: 'HIDE', condition: { scope: '#/properties/kind', schema: { const: 'P' } } }, + elements: [control('physical', label)], + }, + ], + } + + renderForm(uischema, { kind: 'P' }) + expect(screen.queryByText(label)).toBeNull() + + cleanup() + renderForm(uischema, { kind: 'S' }) + expect(screen.getByText(label)).toBeTruthy() + }) +}) diff --git a/packages/jsonforms-renderers/src/renderers/index.ts b/packages/jsonforms-renderers/src/renderers/index.ts index 88af488..26e23ac 100644 --- a/packages/jsonforms-renderers/src/renderers/index.ts +++ b/packages/jsonforms-renderers/src/renderers/index.ts @@ -33,6 +33,7 @@ import ArrayControl from './ArrayControl' import { ArrayControlTester } from './ArrayControlTester' import LabelRenderer, { LabelTester } from './LabelRenderer' import { rankWith, isPrimitiveArrayControl } from '@jsonforms/core' +import { withJsonFormsLayoutProps } from '@jsonforms/react' const PrimitiveArrayControlTester = rankWith(3, isPrimitiveArrayControl) @@ -44,10 +45,13 @@ export const radixRenderers = [ { tester: SearchSelectControlTester, renderer: SearchSelectControl }, { tester: SelectControlTester, renderer: SelectControl }, { tester: DateControlTester, renderer: DateControl }, - { tester: VerticalLayoutTester, renderer: VerticalLayoutRenderer }, - { tester: HorizontalLayoutTester, renderer: HorizontalLayoutRenderer }, - { tester: GroupLayoutTester, renderer: GroupLayoutRenderer }, - { tester: CategorizationLayoutTester, renderer: CategorizationLayoutRenderer }, + // The layout renderers take their props from withJsonFormsLayoutProps, which + // evaluates the layout's rule into `visible` and `enabled`, as + // withJsonFormsControlProps does for the controls. + { tester: VerticalLayoutTester, renderer: withJsonFormsLayoutProps(VerticalLayoutRenderer) }, + { tester: HorizontalLayoutTester, renderer: withJsonFormsLayoutProps(HorizontalLayoutRenderer) }, + { tester: GroupLayoutTester, renderer: withJsonFormsLayoutProps(GroupLayoutRenderer) }, + { tester: CategorizationLayoutTester, renderer: withJsonFormsLayoutProps(CategorizationLayoutRenderer) }, { tester: FileControlTester, renderer: FileControl }, { tester: SpreadsheetControlTester, renderer: SpreadsheetControl }, { tester: SpreadsheetExportControlTester, renderer: SpreadsheetExportControl },