Skip to content

Commit a24969c

Browse files
committed
Add more feature to renderer
1 parent 4791c70 commit a24969c

File tree

3 files changed

+66
-30
lines changed

3 files changed

+66
-30
lines changed

packages/vanilla-renderers/src/complex/categorization/CategorizationRenderer.tsx

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,58 +22,76 @@
2222
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2323
THE SOFTWARE.
2424
*/
25-
import React, { useEffect, useState } from 'react';
25+
import React, { useMemo, useState } from 'react';
2626
import type { Categorization, Category, LayoutProps } from '@jsonforms/core';
27+
import { isVisible } from '@jsonforms/core';
2728
import {
2829
TranslateProps,
2930
withJsonFormsLayoutProps,
3031
withTranslateProps,
3132
} from '@jsonforms/react';
3233
import { CategorizationList } from './CategorizationList';
3334
import { SingleCategory } from './SingleCategory';
34-
import { isCategorization } from './tester';
3535
import { withVanillaControlProps } from '../../util';
36-
import type { VanillaRendererProps } from '../../index';
36+
import type { AjvProps, VanillaRendererProps } from '../../index';
37+
import { withAjvProps } from '../../index';
3738

3839
export interface CategorizationState {
3940
selectedCategory: Category;
4041
}
4142

43+
interface CategorizationProps {
44+
selected?: number;
45+
onChange?(selected: number, prevSelected: number): void;
46+
}
47+
4248
export const CategorizationRenderer = ({
49+
data,
4350
uischema,
4451
schema,
4552
path,
53+
selected,
4654
t,
4755
visible,
4856
getStyleAsClassName,
49-
}: LayoutProps & VanillaRendererProps & TranslateProps) => {
50-
const findCategory = (categorization: Categorization): Category => {
51-
const category = categorization.elements[0];
52-
53-
if (isCategorization(category)) {
54-
return findCategory(category);
55-
}
56-
57-
return category;
58-
};
59-
57+
onChange,
58+
ajv,
59+
}: LayoutProps &
60+
VanillaRendererProps &
61+
TranslateProps &
62+
CategorizationProps &
63+
AjvProps) => {
6064
const categorization = uischema as Categorization;
65+
const categories = useMemo(
66+
() =>
67+
categorization.elements.filter((category: Category) =>
68+
isVisible(category, data, undefined, ajv)
69+
),
70+
[categorization, data, ajv]
71+
) as [Category];
6172
const classNames = getStyleAsClassName('categorization');
6273
const masterClassNames = getStyleAsClassName('categorization.master');
6374
const detailClassNames = getStyleAsClassName('categorization.detail');
6475
const subcategoriesClassName = getStyleAsClassName('category.subcategories');
6576
const groupClassName = getStyleAsClassName('category.group');
6677

67-
useEffect(() => {
68-
setSelectedCategory(findCategory(categorization));
69-
}, [uischema, schema]);
78+
const [previousCategorization, setPreviousCategorization] =
79+
useState<Categorization>(uischema as Categorization);
80+
const [activeCategory, setActiveCategory] = useState<number>(selected ?? 0);
7081

71-
const [selectedCategory, setSelectedCategory] = useState(
72-
findCategory(categorization)
73-
);
82+
const safeCategory =
83+
activeCategory >= categorization.elements.length ? 0 : activeCategory;
7484

75-
const onCategorySelected = (category: Category) => () => {
76-
return setSelectedCategory(category);
85+
if (categorization !== previousCategorization) {
86+
setActiveCategory(0);
87+
setPreviousCategorization(categorization);
88+
}
89+
90+
const onCategorySelected = (categoryIndex: number) => () => {
91+
if (onChange) {
92+
return onChange(categoryIndex, safeCategory);
93+
}
94+
return setActiveCategory(categoryIndex);
7795
};
7896

7997
return (
@@ -84,7 +102,7 @@ export const CategorizationRenderer = ({
84102
<div className={masterClassNames}>
85103
<CategorizationList
86104
categorization={categorization}
87-
selectedCategory={selectedCategory}
105+
selectedCategory={categories[safeCategory]}
88106
depth={0}
89107
onSelect={onCategorySelected}
90108
subcategoriesClassName={subcategoriesClassName}
@@ -94,15 +112,18 @@ export const CategorizationRenderer = ({
94112
</div>
95113
<div className={detailClassNames}>
96114
<SingleCategory
97-
category={selectedCategory}
115+
category={categories[safeCategory]}
98116
schema={schema}
99117
path={path}
118+
key={safeCategory}
100119
/>
101120
</div>
102121
</div>
103122
);
104123
};
105124

106-
export default withVanillaControlProps(
107-
withTranslateProps(withJsonFormsLayoutProps(CategorizationRenderer))
125+
export default withAjvProps(
126+
withVanillaControlProps(
127+
withTranslateProps(withJsonFormsLayoutProps(CategorizationRenderer))
128+
)
108129
);

packages/vanilla-renderers/src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2323
THE SOFTWARE.
2424
*/
25+
import Ajv from 'ajv';
26+
2527
import { RankedTester } from '@jsonforms/core';
2628

2729
import {
@@ -102,6 +104,10 @@ export interface VanillaRendererProps extends WithClassname {
102104
getStyleAsClassName?(string: string, ...args: any[]): string;
103105
}
104106

107+
export interface AjvProps {
108+
ajv: Ajv;
109+
}
110+
105111
export interface WithChildren {
106112
children: any;
107113
}

packages/vanilla-renderers/src/util/index.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,8 @@
2525
export * from './i18nDefaults';
2626
import React, { ComponentType, useMemo } from 'react';
2727
import isEmpty from 'lodash/isEmpty';
28-
import {
28+
import type {
2929
ControlElement,
30-
convertToValidClassName,
31-
getConfig,
3230
JsonFormsState,
3331
OwnPropsOfCell,
3432
OwnPropsOfControl,
@@ -37,9 +35,10 @@ import {
3735
StatePropsOfCell,
3836
StatePropsOfControl,
3937
} from '@jsonforms/core';
38+
import { convertToValidClassName, getAjv, getConfig } from '@jsonforms/core';
4039
import { useJsonForms } from '@jsonforms/react';
4140
import { getStyle, getStyleAsClassName } from '../reducers';
42-
import { VanillaRendererProps } from '../index';
41+
import type { AjvProps, VanillaRendererProps } from '../index';
4342
import { findStyle, findStyleAsClassName } from '../reducers/styling';
4443
import { useStyles } from '../styles';
4544

@@ -240,6 +239,16 @@ const withVanillaCellPropsForType =
240239
);
241240
};
242241

242+
export const withAjvProps = <P extends object>(
243+
Component: ComponentType<AjvProps & P>
244+
) =>
245+
function WithAjvProps(props: P) {
246+
const ctx = useJsonForms();
247+
const ajv = getAjv({ jsonforms: { ...ctx } });
248+
249+
return <Component {...props} ajv={ajv} />;
250+
};
251+
243252
export const withVanillaCellProps =
244253
withVanillaCellPropsForType('control.input');
245254

0 commit comments

Comments
 (0)