Skip to content

Commit bd8c125

Browse files
authoredAug 2, 2024
Merge pull request #6 from react-declarative/tree-view
tree-field
2 parents 2d74f9e + cf02e6d commit bd8c125

22 files changed

+280
-23
lines changed
 

‎demo/package-lock.json

+8-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎demo/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
"react-native": "0.74.1",
1111
"react-native-svg": "15.2.0",
1212
"react-native-web": "~0.19.6",
13-
"rn-declarative": "^0.0.56",
14-
"rn-declarative-eva": "^0.0.44"
13+
"rn-declarative": "^0.0.57",
14+
"rn-declarative-eva": "^0.0.45"
1515
},
1616
"devDependencies": {
1717
"@babel/core": "^7.19.3",

‎packages/rn-declarative-eva/package-lock.json

+6-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/rn-declarative-eva/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rn-declarative-eva",
3-
"version": "0.0.44",
3+
"version": "0.0.45",
44
"description": "A responsive layout for the react-native",
55
"private": false,
66
"author": {
@@ -77,7 +77,7 @@
7777
"react-native": "0.71.6",
7878
"react-native-svg": "9.4.0",
7979
"typescript": "4.6.2",
80-
"rn-declarative": "0.0.56"
80+
"rn-declarative": "0.0.57"
8181
},
8282
"dependencies": {
8383
"rimraf": "3.0.2"

‎packages/rn-declarative/package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/rn-declarative/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rn-declarative",
3-
"version": "0.0.56",
3+
"version": "0.0.57",
44
"description": "A responsive layout for the react-native",
55
"private": false,
66
"author": {

‎packages/rn-declarative/src/components/One/components/SlotFactory/ISlotFactoryContext.ts

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { ISliderSlot } from '../../slots/SliderSlot';
1717
import { ITimeSlot } from '../../slots/TimeSlot';
1818
import { IChooseSlot } from '../../slots/ChooseSlot';
1919
import { ITypographySlot } from '../../slots/TypographySlot';
20+
import { ITreeSlot } from '../../slots/TreeSlot';
2021

2122
/**
2223
* A context object that provides access to various component types used by the slot factory.
@@ -47,6 +48,7 @@ export interface ISlotFactoryContext {
4748
Time: ComponentType<ITimeSlot>;
4849
Choose: ComponentType<IChooseSlot>;
4950
Typography: ComponentType<ITypographySlot>;
51+
Tree: ComponentType<ITreeSlot>;
5052
}
5153

5254
export default ISlotFactoryContext;

‎packages/rn-declarative/src/components/One/components/SlotFactory/SlotContext.ts

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import Slider from './components/Slider';
1717
import Time from './components/Time';
1818
import Choose from './components/Choose';
1919
import Typography from './components/Typography';
20+
import Tree from './components/Tree';
2021

2122
import ISlotFactoryContext from './ISlotFactoryContext';
2223

@@ -48,6 +49,7 @@ export const defaultSlots: ISlotFactoryContext = {
4849
Time,
4950
Choose,
5051
Typography,
52+
Tree,
5153
};
5254

5355
export const SlotContext = createContext<ISlotFactoryContext>(defaultSlots);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import * as React from 'react';
2+
3+
import { Text } from 'react-native';
4+
5+
import { ITreeSlot } from '../../../slots/TreeSlot';
6+
7+
export const Tree = ({}: ITreeSlot) => (
8+
<Text>
9+
FieldType.Tree is not provided (see OneSlotFactory)
10+
</Text>
11+
)
12+
13+
export default Tree;

‎packages/rn-declarative/src/components/One/config/createField.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import SliderField from "../fields/SliderField";
2323
import TimeField from "../fields/TimeField";
2424
import ChooseField from "../fields/ChooseField";
2525
import TypographyField from "../fields/TypographyField";
26+
import TreeField from "../fields/TreeField";
2627

2728
const fieldMap: { [key in FieldType]?: React.ComponentType<IEntity> } = Object.create(null);
2829

@@ -60,6 +61,7 @@ Object.assign(fieldMap, {
6061
[FieldType.Time]: TimeField,
6162
[FieldType.Choose]: ChooseField,
6263
[FieldType.Typography]: TypographyField,
64+
[FieldType.Tree]: TreeField,
6365
});
6466

6567
/**

‎packages/rn-declarative/src/components/One/config/initialValue.ts

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const initialValueMap = {
3232
[FieldType.Time]: null,
3333
[FieldType.Choose]: null,
3434
[FieldType.Typography]: "",
35+
[FieldType.Tree]: null,
3536
};
3637

3738
type InitialValue = typeof initialValueMap;

‎packages/rn-declarative/src/components/One/config/isBaseline.ts

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export const baselineFields = new Set<FieldType>([
2424
FieldType.Time,
2525
FieldType.Choose,
2626
FieldType.Typography,
27+
FieldType.Tree,
2728
]);
2829

2930
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import * as React from "react";
2+
3+
import Tree from '../../../components/One/slots/TreeSlot';
4+
5+
import makeField from "../components/makeField";
6+
7+
import IManaged, { PickProp } from "../../../model/IManaged";
8+
import IAnything from "../../../model/IAnything";
9+
import IField from "../../../model/IField";
10+
11+
/**
12+
* Interface for the props of the ITreeField component.
13+
*
14+
* @template Data The type of data in the field.
15+
* @template Payload The type of payload in the field.
16+
*/
17+
export interface ITreeFieldProps<Data = IAnything, Payload = IAnything> {
18+
/**
19+
* Validation factory config
20+
*
21+
* @template IField - Type representing the field object.
22+
* @template Data - Type representing the data object.
23+
* @template Payload - Type representing the payload object.
24+
*
25+
* @returns The value of the "validation" property.
26+
*/
27+
validation?: PickProp<IField<Data, Payload>, 'validation'>;
28+
/**
29+
* Returns the "description" property of a given object.
30+
*
31+
* @template T - The type of the object.
32+
* @template K - The literal key type.
33+
*
34+
* @param obj - The object from which to extract the property.
35+
* @param key - The literal key representing the property to extract.
36+
*
37+
* @returns - The value of the specified property.
38+
*/
39+
description?: PickProp<IField<Data, Payload>, "description">;
40+
/**
41+
* Type definition for the "title" property picked from the given object type.
42+
*
43+
* @template IField - The object type that contains the "title" property.
44+
* @template Data - The data type of the "title" property.
45+
* @template Payload - The payload type of the "title" property.
46+
*
47+
* @param - The object from which the "title" property will be picked.
48+
*
49+
* @returns - The resulting object that only contains the "title" property.
50+
*/
51+
title?: PickProp<IField<Data, Payload>, "title">;
52+
/**
53+
* Type definition for the variable placeholder.
54+
*
55+
* @template Data - The type of data for the field.
56+
* @template Payload - The type of payload for the field.
57+
* @typedef placeholder
58+
*/
59+
placeholder?: PickProp<IField<Data, Payload>, "placeholder">;
60+
/**
61+
* Specifies if a field is readOnly.
62+
*
63+
* @typedef Readonly
64+
*
65+
* @typedef IField
66+
* @typedef Payload
67+
* @typedef PickProp
68+
* @typedef Data
69+
*
70+
* @param readonly - The field being checked for readOnly status.
71+
*
72+
* @returns - A boolean value indicating if the field is readOnly.
73+
*/
74+
readonly?: PickProp<IField<Data, Payload>, "readonly">;
75+
/**
76+
* Represents the `disabled` property of a field in a form.
77+
*
78+
* @typedef Disabled
79+
*
80+
* @property disabled - Indicates whether the field is disabled or not.
81+
* @template Data - The type of data stored in the form.
82+
* @template Payload - The type of payload used for form submission.
83+
*/
84+
disabled?: PickProp<IField<Data, Payload>, "disabled">;
85+
/**
86+
* Represents the item tree of a specific field in the data payload.
87+
*
88+
* @typedef ItemTree
89+
*/
90+
itemTree?: PickProp<IField<Data, Payload>, 'itemTree'>;
91+
}
92+
93+
/**
94+
* Represents the private interface for the TreeField component.
95+
*
96+
* @template Data The type of data for the TreeField component.
97+
*/
98+
export interface ITreeFieldPrivate<Data = IAnything> {
99+
onChange: PickProp<IManaged<Data>, "onChange">;
100+
invalid: PickProp<IManaged<Data>, "invalid">;
101+
incorrect: PickProp<IManaged<Data>, "incorrect">;
102+
value: PickProp<IManaged<Data>, "value">;
103+
loading: PickProp<IManaged<Data>, "loading">;
104+
disabled: PickProp<IManaged<Data>, "disabled">;
105+
dirty: PickProp<IManaged<Data>, "dirty">;
106+
name: PickProp<IManaged<Data>, "name">;
107+
}
108+
109+
/**
110+
* Renders a TreeField component.
111+
*
112+
* @param props - The props object containing the necessary data for rendering the TreeField.
113+
* @param props.invalid - Determines if the TreeField is invalid.
114+
* @param props.value - The value of the TreeField.
115+
* @param props.disabled - Determines if the TreeField is disabled.
116+
* @param props.readonly - Determines if the TreeField is readonly.
117+
* @param props.incorrect - Determines if the TreeField is incorrect.
118+
* @param props.description - The description text for the TreeField.
119+
* @param props.outlined - Determines if the TreeField should have an outlined style.
120+
* @param props.title - The title text for the TreeField.
121+
* @param props.placeholder - The placeholder text for the TreeField.
122+
* @param props.itemTree - The itemTree object for rendering the Tree.
123+
* @param props.dirty - Determines if the TreeField has been modified.
124+
* @param props.loading - Determines if the TreeField is currently loading.
125+
* @param props.onChange - The callback function to be called when the value of the TreeField changes.
126+
* @param props.name - The name attribute of the TreeField.
127+
* @param props.withContextMenu - Determines if the TreeField should have a context menu.
128+
*
129+
* @returns The rendered TreeField component.
130+
*/
131+
export const TreeField = ({
132+
invalid,
133+
value,
134+
disabled,
135+
readonly,
136+
incorrect,
137+
description = "",
138+
title = "",
139+
placeholder = "",
140+
itemTree,
141+
dirty,
142+
loading,
143+
onChange,
144+
name,
145+
}: ITreeFieldProps & ITreeFieldPrivate) => (
146+
<Tree
147+
invalid={invalid}
148+
incorrect={incorrect}
149+
value={value}
150+
readonly={readonly}
151+
disabled={disabled}
152+
description={description}
153+
title={title}
154+
placeholder={placeholder}
155+
itemTree={itemTree}
156+
dirty={dirty}
157+
loading={loading}
158+
onChange={onChange}
159+
name={name}
160+
/>
161+
);
162+
163+
TreeField.displayName = 'TreeField';
164+
165+
export default makeField(TreeField, {
166+
withApplyQueue: true,
167+
skipDirtyPressListener: true,
168+
skipFocusReadonly: true,
169+
skipDebounce: true,
170+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { ITreeFieldProps, ITreeFieldPrivate } from "../../fields/TreeField";
2+
3+
type ITreeBase = ITreeFieldProps & ITreeFieldPrivate;
4+
5+
/**
6+
* Represents a slot in a tree structure.
7+
* Extends the interface ITreeBase.
8+
*
9+
* @interface
10+
* @extends ITreeBase
11+
*/
12+
export interface ITreeSlot extends ITreeBase { }
13+
14+
export default ITreeSlot;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import * as React from 'react';
2+
import { useContext } from 'react';
3+
4+
import { SlotContext } from '../../components/SlotFactory';
5+
6+
import ITreeSlot from './ITreeSlot';
7+
8+
/**
9+
* Represents a slot for a tree component.
10+
*
11+
* @param props - The props for the TreeSlot component.
12+
* @returns - The rendered Tree component.
13+
*/
14+
export const TreeSlot = (props: ITreeSlot) => {
15+
const { Tree } = useContext(SlotContext);
16+
return <Tree {...props} />;
17+
};
18+
19+
export default TreeSlot;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './ITreeSlot';
2+
export * from './TreeSlot';
3+
export { default } from './TreeSlot';

‎packages/rn-declarative/src/components/One/slots/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ export * from './SliderSlot';
1414
export * from './TimeSlot';
1515
export * from './ChooseSlot';
1616
export * from './TypographySlot';
17+
export * from './TreeSlot';

‎packages/rn-declarative/src/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export type { ISize } from './model/ISize';
22

33
import { TypedField as TypedFieldInternal } from './model/TypedField';
44
import { IValidation as IValidationInternal } from './model/IValidation';
5+
import { ITreeNode as ITreeNodeInternal } from './model/ITreeNode';
56
import { IInvalidField as IInvalidFieldInternal } from './model/IInvalidField';
67
import { StyleProperties as StylePropertiesInternal } from './model/StyleProperties';
78
import { CompiledStyles as CompiledStylesInternal } from './model/CompiledStyles';
@@ -49,6 +50,7 @@ export type IFieldEntity<Data = IAnything, Payload = IAnything> = IEntityInterna
4950
export type IFieldManaged<Data = IAnything, Value = IAnything> = IManagedInternal<Data, Value>;
5051
export type IInvalidField<Data = IAnything, Payload = IAnything> = IInvalidFieldInternal<Data, Payload>;
5152
export type IValidation = IValidationInternal;
53+
export type ITreeNode = ITreeNodeInternal;
5254
export type StyleProperties = StylePropertiesInternal;
5355
export type CompiledStyles = CompiledStylesInternal;
5456

@@ -112,6 +114,8 @@ import { ISliderSlot as ISliderSlotInternal } from './components';
112114
import { ITimeSlot as ITimeSlotInternal } from './components';
113115
import { IChooseSlot as IChooseSlotInternal } from './components';
114116
import { ITypographySlot as ITypographySlotInternal } from './components';
117+
import { ITreeSlot as ITreeSlotInternal } from './components';
118+
115119

116120
export type ICheckBoxSlot = ICheckBoxSlotInternal;
117121
export type IComboSlot = IComboSlotInternal;
@@ -130,6 +134,7 @@ export type ISliderSlot = ISliderSlotInternal;
130134
export type ITimeSlot = ITimeSlotInternal;
131135
export type IChooseSlot = IChooseSlotInternal;
132136
export type ITypographySlot = ITypographySlotInternal;
137+
export type ITreeSlot = ITreeSlotInternal;
133138

134139
export { randomString } from './utils/randomString';
135140
export { compareFulltext } from './utils/compareFulltext';

‎packages/rn-declarative/src/model/FieldType.ts

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export enum FieldType {
2626
Time = 'time-field',
2727
Choose = 'choose-field',
2828
Typography = 'typography-field',
29+
Tree = 'Tree-field',
2930
};
3031

3132
Object.entries(FieldType).forEach(([key, value]) => {

‎packages/rn-declarative/src/model/IField.ts

+7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import type { IDebug } from './ComponentFieldInstance';
66
import FieldType from './FieldType';
77
import IAnything from './IAnything';
88
import IValidation from './IValidation';
9+
import ITreeNode from './ITreeNode';
10+
911
import StyleProperties from './StyleProperties';
1012

1113
/**
@@ -176,6 +178,11 @@ export interface IField<Data = IAnything, Payload = IAnything> {
176178
*/
177179
itemList?: string[] | ((data: Data, payload: Payload) => string[]) | ((data: Data, payload: Payload) => Promise<string[]>),
178180

181+
/**
182+
* Вариант выбора для TreeField
183+
*/
184+
itemTree?: ITreeNode[] | ((data: Data, payload: Payload) => ITreeNode[]) | ((data: Data, payload: Payload) => Promise<ITreeNode[]>);
185+
179186
/**
180187
* Отключает возможность сброса выбора значения для Items и Combo
181188
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Represents a Node in a tree structure.
3+
*/
4+
export interface ITreeNode {
5+
label: string;
6+
value: string;
7+
/**
8+
* Represents an array of child nodes excluding the "child" property (recursion).
9+
*
10+
* @typedef ChildArray
11+
*/
12+
child?: Omit<ITreeNode, "child">[];
13+
}
14+
15+
export default ITreeNode;

‎packages/rn-declarative/src/model/TypedField.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { ISliderFieldProps } from '../components/One/fields/SliderField';
3535
import { ITimeFieldProps } from '../components/One/fields/TimeField';
3636
import { IChooseFieldProps } from '../components/One/fields/ChooseField';
3737
import { ITypographyFieldProps } from '../components/One/fields/TypographyField';
38+
import { ITreeFieldProps } from '../components/One/fields/TreeField';
3839

3940
/**
4041
* Исключения из правила
@@ -111,7 +112,7 @@ type Slider<Data = IAnything, Payload = IAnything> = TypedFieldFactoryShallow<Fi
111112
type Time<Data = IAnything, Payload = IAnything> = TypedFieldFactoryShallow<FieldType.Time, ITimeFieldProps<Data, Payload>, Data, Payload>;
112113
type Choose<Data = IAnything, Payload = IAnything> = TypedFieldFactoryShallow<FieldType.Choose, IChooseFieldProps<Data, Payload>, Data, Payload>;
113114
type Typography<Data = IAnything, Payload = IAnything> = TypedFieldFactoryShallow<FieldType.Typography, ITypographyFieldProps<Data, Payload>, Data, Payload>;
114-
115+
type Tree<Data = IAnything, Payload = IAnything> = TypedFieldFactoryShallow<FieldType.Tree, ITreeFieldProps<Data, Payload>, Data, Payload>;
115116

116117
/**
117118
* Логическое ветвление компонентов
@@ -130,6 +131,7 @@ export type TypedFieldRegistry<Data = IAnything, Payload = IAnything, Target = a
130131
: Target extends Time<Data, Payload> ? Time<Data, Payload>
131132
: Target extends Choose<Data, Payload> ? Choose<Data, Payload>
132133
: Target extends Typography<Data, Payload> ? Typography<Data, Payload>
134+
: Target extends Tree<Data, Payload> ? Tree<Data, Payload>
133135
: Target extends Component<Data, Payload> ? Component<Data, Payload>
134136
: Target extends Items<Data, Payload> ? Items<Data, Payload>
135137
: Target extends Radio<Data, Payload> ? Radio<Data, Payload>

0 commit comments

Comments
 (0)
Please sign in to comment.