Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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<string, unknown>) {
render(
<Theme>
<JsonForms schema={schema} uischema={uischema as UISchemaElement} data={data} renderers={radixRenderers} />
</Theme>,
)
}

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()
})
})
12 changes: 8 additions & 4 deletions packages/jsonforms-renderers/src/renderers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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 },
Expand Down
Loading