From f8922a42d9c6a904cca7fe3c8de0406de3d12eba Mon Sep 17 00:00:00 2001 From: Lucas Koehler Date: Thu, 22 Jan 2026 18:03:31 +0100 Subject: [PATCH 1/2] Remove usage of lodash/isArray for improved type guarding --- packages/core/src/testers/testers.ts | 3 +-- packages/core/src/util/util.ts | 3 +-- packages/vue-vuetify/src/controls/StringControlRenderer.vue | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/core/src/testers/testers.ts b/packages/core/src/testers/testers.ts index afd96335ac..ac2f449b6b 100644 --- a/packages/core/src/testers/testers.ts +++ b/packages/core/src/testers/testers.ts @@ -27,7 +27,6 @@ import isEmpty from 'lodash/isEmpty'; import get from 'lodash/get'; import endsWith from 'lodash/endsWith'; import last from 'lodash/last'; -import isArray from 'lodash/isArray'; import reduce from 'lodash/reduce'; import toPairs from 'lodash/toPairs'; import includes from 'lodash/includes'; @@ -483,7 +482,7 @@ const traverse = ( pred: (obj: JsonSchema) => boolean, rootSchema: JsonSchema ): boolean => { - if (isArray(any)) { + if (Array.isArray(any)) { return reduce( any, (acc, el) => acc || traverse(el, pred, rootSchema), diff --git a/packages/core/src/util/util.ts b/packages/core/src/util/util.ts index 959651e433..ed4eae93d9 100644 --- a/packages/core/src/util/util.ts +++ b/packages/core/src/util/util.ts @@ -24,7 +24,6 @@ */ import isEmpty from 'lodash/isEmpty'; -import isArray from 'lodash/isArray'; import includes from 'lodash/includes'; import find from 'lodash/find'; import { resolveData, resolveSchema } from './resolvers'; @@ -100,7 +99,7 @@ export const deriveTypes = (jsonSchema: JsonSchema): string[] => { if (!isEmpty(jsonSchema.type) && typeof jsonSchema.type === 'string') { return [jsonSchema.type]; } - if (isArray(jsonSchema.type)) { + if (Array.isArray(jsonSchema.type)) { return jsonSchema.type; } if ( diff --git a/packages/vue-vuetify/src/controls/StringControlRenderer.vue b/packages/vue-vuetify/src/controls/StringControlRenderer.vue index 3e7263d6e0..334d4ad9b4 100644 --- a/packages/vue-vuetify/src/controls/StringControlRenderer.vue +++ b/packages/vue-vuetify/src/controls/StringControlRenderer.vue @@ -88,7 +88,6 @@ import { type RendererProps, } from '@jsonforms/vue'; import every from 'lodash/every'; -import isArray from 'lodash/isArray'; import isString from 'lodash/isString'; import { defineComponent } from 'vue'; import { VCombobox, VTextField } from 'vuetify/components'; @@ -123,7 +122,7 @@ const controlRenderer = defineComponent({ if ( suggestions === undefined || - !isArray(suggestions) || + !Array.isArray(suggestions) || !every(suggestions, isString) ) { // check for incorrect data From 5fcd38a9d68b6f2a96293871ce6e9f302d45b481 Mon Sep 17 00:00:00 2001 From: Lucas Koehler Date: Thu, 12 Feb 2026 17:17:56 +0100 Subject: [PATCH 2/2] react: Remove usage of removed React.StatelessComponent --- .../renderers/MaterialArrayControl.test.tsx | 6 ++--- packages/react/src/Renderer.tsx | 5 ++-- .../react/test/renderers/JsonForms.test.tsx | 25 ++++++++----------- .../src/cells/BooleanCell.tsx | 5 +--- 4 files changed, 17 insertions(+), 24 deletions(-) diff --git a/packages/material-renderers/test/renderers/MaterialArrayControl.test.tsx b/packages/material-renderers/test/renderers/MaterialArrayControl.test.tsx index 6a2b17bf26..8026c84c0f 100644 --- a/packages/material-renderers/test/renderers/MaterialArrayControl.test.tsx +++ b/packages/material-renderers/test/renderers/MaterialArrayControl.test.tsx @@ -34,7 +34,7 @@ import MaterialArrayControlRenderer from '../../src/complex/MaterialArrayControl import { materialCells, materialRenderers } from '../../src'; import Enzyme, { mount, ReactWrapper } from 'enzyme'; import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; -import { JsonFormsStateProvider, StatelessRenderer } from '@jsonforms/react'; +import { JsonFormsStateProvider } from '@jsonforms/react'; import { initCore, TestEmitter } from './util'; import { checkTooltip, checkTooltipTranslation } from './tooltipChecker'; @@ -376,10 +376,10 @@ describe('Material array control', () => { expect(onChangeData.data.length).toBe(1); }); - const CellRenderer1: StatelessRenderer = () => ( + const CellRenderer1: React.FC = () => (
); - const CellRenderer2: StatelessRenderer = () => ( + const CellRenderer2: React.FC = () => (
); diff --git a/packages/react/src/Renderer.tsx b/packages/react/src/Renderer.tsx index b07cdca198..1ba4c59822 100644 --- a/packages/react/src/Renderer.tsx +++ b/packages/react/src/Renderer.tsx @@ -46,9 +46,10 @@ export class RendererComponent< * Stateless Renderer. * * @template P type of any renderer props + * @deprecated Use React.FunctionComponent instead */ export type StatelessRenderer

= - React.StatelessComponent

; + React.FunctionComponent

; /** * Represents a Renderer, which might either be a component or a function. @@ -57,4 +58,4 @@ export type Renderer = // TODO fix @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types | RendererComponent - | StatelessRenderer; + | React.FunctionComponent; diff --git a/packages/react/test/renderers/JsonForms.test.tsx b/packages/react/test/renderers/JsonForms.test.tsx index d863fb6bb9..fb142d4f16 100644 --- a/packages/react/test/renderers/JsonForms.test.tsx +++ b/packages/react/test/renderers/JsonForms.test.tsx @@ -50,7 +50,6 @@ import { } from '@jsonforms/core'; import { isEqual } from 'lodash'; import Enzyme, { mount, shallow } from 'enzyme'; -import type { StatelessRenderer } from '../../src/Renderer'; import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; import { JsonForms, @@ -114,13 +113,13 @@ export const initJsonFormsStore = ({ return createStore(reducer, initState); }; -const CustomRenderer1: StatelessRenderer = () =>

test

; -const CustomRenderer2: StatelessRenderer = () =>

test

; -const CustomRenderer3: StatelessRenderer = () =>

test

; -const CellRenderer1: StatelessRenderer = () => ( +const CustomRenderer1: React.FC = () =>

test

; +const CustomRenderer2: React.FC = () =>

test

; +const CustomRenderer3: React.FC = () =>

test

; +const CellRenderer1: React.FC = () => (

test

); -const CellRenderer2: StatelessRenderer = () => ( +const CellRenderer2: React.FC = () => (

test

); @@ -256,7 +255,7 @@ test('ids should be unique within the same form', () => { }); const ids: string[] = []; - const MyCustomRenderer: StatelessRenderer = (props: any) => { + const MyCustomRenderer: React.FC = (props: any) => { ids.push(props.id); return
Custom
; }; @@ -432,9 +431,7 @@ test('JsonForms renderer should pick most applicable cell renderer via ownProps' }); store.dispatch(registerCell(() => 50, CellRenderer1)); - const ArrayRenderer: StatelessRenderer = ( - props: RendererProps - ) => { + const ArrayRenderer: React.FC = (props: RendererProps) => { return ( { }); test('JsonForms renderer should pick enabled prop from ownProps', () => { - const CustomRenderer4: StatelessRenderer = ( - props: RendererProps - ) => { + const CustomRenderer4: React.FC = (props: RendererProps) => { return

{`${props.enabled}`}

; }; @@ -1010,7 +1005,7 @@ test('JsonForms should update if data prop is updated', () => { }); test('JsonForms should use additionalErrors if provided', () => { - const CustomRendererWithError: StatelessRenderer = ({ + const CustomRendererWithError: React.FC = ({ errors, }: ControlProps) => { return
{errors}
; @@ -1048,7 +1043,7 @@ test('JsonForms should use additionalErrors if provided', () => { }); test('JsonForms should use react to additionalErrors update', () => { - const CustomRendererWithError: StatelessRenderer = ({ + const CustomRendererWithError: React.FC = ({ errors, }: ControlProps) => { return
{errors}
; diff --git a/packages/vanilla-renderers/src/cells/BooleanCell.tsx b/packages/vanilla-renderers/src/cells/BooleanCell.tsx index efb76ebe6d..2213ad0406 100644 --- a/packages/vanilla-renderers/src/cells/BooleanCell.tsx +++ b/packages/vanilla-renderers/src/cells/BooleanCell.tsx @@ -30,13 +30,10 @@ import { rankWith, } from '@jsonforms/core'; import { withJsonFormsCellProps } from '@jsonforms/react'; -import type { StatelessComponent } from 'react'; import type { VanillaRendererProps } from '../index'; import { withVanillaBooleanCellProps } from '../util/index'; -export const BooleanCell: StatelessComponent = ( - props: CellProps & VanillaRendererProps -) => { +export const BooleanCell = (props: CellProps & VanillaRendererProps) => { const { data, className, id, enabled, uischema, path, handleChange } = props; return (