diff --git a/demo/package-lock.json b/demo/package-lock.json index c67ecd0..8d13a0f 100644 --- a/demo/package-lock.json +++ b/demo/package-lock.json @@ -18,8 +18,8 @@ "react-native": "0.74.1", "react-native-svg": "15.2.0", "react-native-web": "~0.19.6", - "rn-declarative": "^0.0.54", - "rn-declarative-eva": "^0.0.42" + "rn-declarative": "^0.0.55", + "rn-declarative-eva": "^0.0.43" }, "devDependencies": { "@babel/core": "^7.19.3", @@ -10975,9 +10975,9 @@ } }, "node_modules/rn-declarative": { - "version": "0.0.54", - "resolved": "https://registry.npmjs.org/rn-declarative/-/rn-declarative-0.0.54.tgz", - "integrity": "sha512-IZs4grXhM8pSXMnuVhhX2luemrvv6Am3obEPmeU5RFMHUboCg4aRLlEY2K4uaZYMgNggzGixjB64LiPeQKnDQg==", + "version": "0.0.55", + "resolved": "https://registry.npmjs.org/rn-declarative/-/rn-declarative-0.0.55.tgz", + "integrity": "sha512-qPUTVp1n03/SLAUkYQWexwugTDAgO3VWyPoc2jHKe+WXOao8YtNdOS2a8jdFMlVp96W3iDyqIwxS9U9p7hpMyw==", "hasInstallScript": true, "dependencies": { "rimraf": "3.0.2" @@ -10995,9 +10995,9 @@ } }, "node_modules/rn-declarative-eva": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/rn-declarative-eva/-/rn-declarative-eva-0.0.42.tgz", - "integrity": "sha512-SHv5jdDiC68uH/0awfw0YV46aQH1SO8u3OzDHvBT7gWIieMPEfOiSKZkfsCGxeiHM1q1p6tWI4xdsl7ILIbGIQ==", + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/rn-declarative-eva/-/rn-declarative-eva-0.0.43.tgz", + "integrity": "sha512-j2JnZ7ezx099H5McEOaK3AH+u2mlHL6XD7odDUe5UMYtNY5ZHPQ3dnOOa7FlUBgTknIk08fwnUbAptBeuLP4Ew==", "hasInstallScript": true, "dependencies": { "rimraf": "3.0.2" diff --git a/demo/package.json b/demo/package.json index e075d28..b02762b 100644 --- a/demo/package.json +++ b/demo/package.json @@ -10,8 +10,8 @@ "react-native": "0.74.1", "react-native-svg": "15.2.0", "react-native-web": "~0.19.6", - "rn-declarative": "^0.0.54", - "rn-declarative-eva": "^0.0.42" + "rn-declarative": "^0.0.55", + "rn-declarative-eva": "^0.0.43" }, "devDependencies": { "@babel/core": "^7.19.3", diff --git a/packages/rn-declarative-eva/README.md b/packages/rn-declarative-eva/README.md index 23ba068..5b583a7 100644 --- a/packages/rn-declarative-eva/README.md +++ b/packages/rn-declarative-eva/README.md @@ -1,6 +1,6 @@ # ⚛️ rn-declarative -> Responsive layout for the `react-native` +> Responsive layout for `react-native` ![screencast](./assets/screencast.gif) diff --git a/packages/rn-declarative-eva/package-lock.json b/packages/rn-declarative-eva/package-lock.json index cd41305..dc8a374 100644 --- a/packages/rn-declarative-eva/package-lock.json +++ b/packages/rn-declarative-eva/package-lock.json @@ -1,12 +1,12 @@ { "name": "rn-declarative-eva", - "version": "0.0.42", + "version": "0.0.43", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rn-declarative-eva", - "version": "0.0.42", + "version": "0.0.43", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -28,7 +28,7 @@ "react": "18.2.0", "react-native": "0.71.6", "react-native-svg": "9.4.0", - "rn-declarative": "0.0.37", + "rn-declarative": "0.0.55", "typescript": "4.6.2" }, "engines": { @@ -9449,9 +9449,9 @@ } }, "node_modules/rn-declarative": { - "version": "0.0.37", - "resolved": "https://registry.npmjs.org/rn-declarative/-/rn-declarative-0.0.37.tgz", - "integrity": "sha512-7rQtrixJlI/ekAsiPasX0ydCEOidBH+sRat1VgykmTeMf65+sZwIe9CGGB4iKK6EXDkQTP24bZIzUyO6x+iJcA==", + "version": "0.0.55", + "resolved": "https://registry.npmjs.org/rn-declarative/-/rn-declarative-0.0.55.tgz", + "integrity": "sha512-qPUTVp1n03/SLAUkYQWexwugTDAgO3VWyPoc2jHKe+WXOao8YtNdOS2a8jdFMlVp96W3iDyqIwxS9U9p7hpMyw==", "dev": true, "hasInstallScript": true, "dependencies": { diff --git a/packages/rn-declarative-eva/package.json b/packages/rn-declarative-eva/package.json index 10bd25e..20da3b8 100644 --- a/packages/rn-declarative-eva/package.json +++ b/packages/rn-declarative-eva/package.json @@ -1,6 +1,6 @@ { "name": "rn-declarative-eva", - "version": "0.0.42", + "version": "0.0.43", "description": "A responsive layout for the react-native", "private": false, "author": { @@ -77,7 +77,7 @@ "react-native": "0.71.6", "react-native-svg": "9.4.0", "typescript": "4.6.2", - "rn-declarative": "0.0.37" + "rn-declarative": "0.0.55" }, "dependencies": { "rimraf": "3.0.2" diff --git a/packages/rn-declarative/README.md b/packages/rn-declarative/README.md index 23ba068..5b583a7 100644 --- a/packages/rn-declarative/README.md +++ b/packages/rn-declarative/README.md @@ -1,6 +1,6 @@ # ⚛️ rn-declarative -> Responsive layout for the `react-native` +> Responsive layout for `react-native` ![screencast](./assets/screencast.gif) diff --git a/packages/rn-declarative/package-lock.json b/packages/rn-declarative/package-lock.json index ffd0874..4da34da 100644 --- a/packages/rn-declarative/package-lock.json +++ b/packages/rn-declarative/package-lock.json @@ -1,12 +1,12 @@ { "name": "rn-declarative", - "version": "0.0.54", + "version": "0.0.55", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rn-declarative", - "version": "0.0.54", + "version": "0.0.55", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/packages/rn-declarative/package.json b/packages/rn-declarative/package.json index f396df5..2175118 100644 --- a/packages/rn-declarative/package.json +++ b/packages/rn-declarative/package.json @@ -1,6 +1,6 @@ { "name": "rn-declarative", - "version": "0.0.54", + "version": "0.0.55", "description": "A responsive layout for the react-native", "private": false, "author": { diff --git a/packages/rn-declarative/src/components/One/components/SlotFactory/ISlotFactoryContext.ts b/packages/rn-declarative/src/components/One/components/SlotFactory/ISlotFactoryContext.ts index 2329b08..9c6b686 100644 --- a/packages/rn-declarative/src/components/One/components/SlotFactory/ISlotFactoryContext.ts +++ b/packages/rn-declarative/src/components/One/components/SlotFactory/ISlotFactoryContext.ts @@ -15,6 +15,7 @@ import { IProgressSlot } from '../../slots/ProgressSlot'; import { IRatingSlot } from '../../slots/RatingSlot'; import { ISliderSlot } from '../../slots/SliderSlot'; import { ITimeSlot } from '../../slots/TimeSlot'; +import { IChooseSlot } from '../../slots/ChooseSlot'; /** * A context object that provides access to various component types used by the slot factory. @@ -43,6 +44,7 @@ export interface ISlotFactoryContext { Rating: ComponentType; Slider: ComponentType; Time: ComponentType; + Choose: ComponentType; } export default ISlotFactoryContext; diff --git a/packages/rn-declarative/src/components/One/components/SlotFactory/SlotContext.ts b/packages/rn-declarative/src/components/One/components/SlotFactory/SlotContext.ts index df33d2c..a06a3d5 100644 --- a/packages/rn-declarative/src/components/One/components/SlotFactory/SlotContext.ts +++ b/packages/rn-declarative/src/components/One/components/SlotFactory/SlotContext.ts @@ -15,6 +15,7 @@ import Progress from './components/Progress'; import Rating from './components/Rating'; import Slider from './components/Slider'; import Time from './components/Time'; +import Choose from './components/Choose'; import ISlotFactoryContext from './ISlotFactoryContext'; @@ -44,6 +45,7 @@ export const defaultSlots: ISlotFactoryContext = { Rating, Slider, Time, + Choose, }; export const SlotContext = createContext(defaultSlots); diff --git a/packages/rn-declarative/src/components/One/components/SlotFactory/components/Choose.tsx b/packages/rn-declarative/src/components/One/components/SlotFactory/components/Choose.tsx new file mode 100644 index 0000000..9881536 --- /dev/null +++ b/packages/rn-declarative/src/components/One/components/SlotFactory/components/Choose.tsx @@ -0,0 +1,13 @@ +import * as React from 'react'; + +import { Text } from 'react-native'; + +import { IChooseSlot } from '../../../slots/ChooseSlot'; + +export const Choose = ({}: IChooseSlot) => ( + + FieldType.Choose is not provided (see OneSlotFactory) + +) + +export default Choose; diff --git a/packages/rn-declarative/src/components/One/config/createField.tsx b/packages/rn-declarative/src/components/One/config/createField.tsx index 87e20d3..14b7e04 100644 --- a/packages/rn-declarative/src/components/One/config/createField.tsx +++ b/packages/rn-declarative/src/components/One/config/createField.tsx @@ -21,6 +21,7 @@ import ProgressField from "../fields/ProgressField"; import RatingField from "../fields/RatingField"; import SliderField from "../fields/SliderField"; import TimeField from "../fields/TimeField"; +import ChooseField from "../fields/ChooseField"; const fieldMap: { [key in FieldType]?: React.ComponentType } = Object.create(null); @@ -56,6 +57,7 @@ Object.assign(fieldMap, { [FieldType.Rating]: RatingField, [FieldType.Slider]: SliderField, [FieldType.Time]: TimeField, + [FieldType.Choose]: ChooseField, }); /** diff --git a/packages/rn-declarative/src/components/One/config/initialValue.ts b/packages/rn-declarative/src/components/One/config/initialValue.ts index c5323a7..c19caa2 100644 --- a/packages/rn-declarative/src/components/One/config/initialValue.ts +++ b/packages/rn-declarative/src/components/One/config/initialValue.ts @@ -30,6 +30,7 @@ const initialValueMap = { [FieldType.Rating]: null, [FieldType.Slider]: 0, [FieldType.Time]: null, + [FieldType.Choose]: null, }; type InitialValue = typeof initialValueMap; diff --git a/packages/rn-declarative/src/components/One/config/isBaseline.ts b/packages/rn-declarative/src/components/One/config/isBaseline.ts index c2a25d0..a1c410c 100644 --- a/packages/rn-declarative/src/components/One/config/isBaseline.ts +++ b/packages/rn-declarative/src/components/One/config/isBaseline.ts @@ -22,6 +22,7 @@ export const baselineFields = new Set([ FieldType.Rating, FieldType.Slider, FieldType.Time, + FieldType.Choose, ]); /** diff --git a/packages/rn-declarative/src/components/One/fields/ChooseField.tsx b/packages/rn-declarative/src/components/One/fields/ChooseField.tsx new file mode 100644 index 0000000..8455fff --- /dev/null +++ b/packages/rn-declarative/src/components/One/fields/ChooseField.tsx @@ -0,0 +1,153 @@ +import * as React from "react"; + +import Choose from '../../../components/One/slots/ChooseSlot'; + +import makeField from "../components/makeField"; + +import IManaged, { PickProp } from "../../../model/IManaged"; +import IAnything from "../../../model/IAnything"; +import IField from "../../../model/IField"; + +/** + * Props for the IChooseField component. + * + * @template Data - The data type of the field. + * @template Payload - The payload type of the field. + */ +export interface IChooseFieldProps { + /** + * Validation factory config + * + * @template IField - Type representing the field object. + * @template Data - Type representing the data object. + * @template Payload - Type representing the payload object. + * + * @returns The value of the "validation" property. + */ + validation?: PickProp, 'validation'>; + /** + * Retrieves the "description" property from the given object. + * + * @template IField - Type representing the field object. + * @template Data - Type representing the data object. + * @template Payload - Type representing the payload object. + * + * @param obj - The object from which to pick the "description" property. + * + * @returns The value of the "description" property. + */ + description?: PickProp, "description">; + /** + * Type definition for the `title` property when using `PickProp` utility. + * @template T - The type of the object from which to pick the property. + * @template Prop - The name of the property to pick. + * @param obj - The object from which to pick the property. + * @param prop - The name of the property to pick. + * @returns - The picked property value. + */ + title?: PickProp, "title">; + /** + * Type definition for a generic placeholder value. + * @typedef Placeholder + */ + placeholder?: PickProp, "placeholder">; + /** + * A variable that represents the `readonly` property of a field. + * + * @typedef readonly? - The `readonly` property of a field. + */ + readonly?: PickProp, "readonly">; + /** + * Type definition for the "disabled" property of a field. + * + * This type is used to define the "disabled" property of a field from an object type "Data" + * and a type "Payload" using the PickProp utility type. + * + * @template Data - The type representing the object structure. + * @template Payload - The type representing the additional properties of the field. + * @typedef disabled + */ + disabled?: PickProp, "disabled">; + /** + * Type definition for the 'choose' property of IField. + * + * @template Data - The data type of the field. + * @template Payload - The data payload for the field. + */ + choose?: PickProp, 'choose'>; + /** + * Represents a possible translation for a field in a form. + * + * @typedef tr + * @property type - The type of translation. + * @property required - Indicates if the translation is required. + * @property options - The list of available translation options. + * @property defaultValue - The default translation value. + */ + tr?: PickProp, 'tr'>; +} + +/** + * Represents an interface for choosing private fields. + * + * @template Data - The type of data for the private fields. + */ +export interface IChooseFieldPrivate { + onChange: PickProp, "onChange">; + invalid: PickProp, "invalid">; + incorrect: PickProp, "incorrect">; + value: PickProp, "value">; + loading: PickProp, "loading">; + disabled: PickProp, "disabled">; + dirty: PickProp, "dirty">; + name: PickProp, "name">; +} + +/** + * Represents the ChooseField component. + * @param options - The options for the ChooseField component. + * @returns The rendered ChooseField component. + */ +export const ChooseField = ({ + invalid, + value, + disabled, + readonly, + incorrect, + description = "", + title = "", + placeholder = "", + choose, + tr, + dirty, + loading, + onChange, + name, +}: IChooseFieldProps & IChooseFieldPrivate) => ( + +); + +ChooseField.displayName = 'ChooseField'; + +export default makeField(ChooseField, { + withApplyQueue: true, + skipDirtyPressListener: true, + skipFocusReadonly: true, + skipFocusBlurCall: true, + skipDebounce: true, +}); diff --git a/packages/rn-declarative/src/components/One/slots/ChooseSlot/ChooseSlot.tsx b/packages/rn-declarative/src/components/One/slots/ChooseSlot/ChooseSlot.tsx new file mode 100644 index 0000000..ec60de0 --- /dev/null +++ b/packages/rn-declarative/src/components/One/slots/ChooseSlot/ChooseSlot.tsx @@ -0,0 +1,19 @@ +import * as React from 'react'; +import { useContext } from 'react'; + +import { SlotContext } from '../../components/SlotFactory'; + +import IChooseSlot from './IChooseSlot'; + +/** + * Renders the component by passing the properties to the Choose component obtained from the SlotContext. + * + * @param props - The properties for the ChooseSlot component. + * @returns - The rendered Choose component. + */ +export const ChooseSlot = (props: IChooseSlot) => { + const { Choose } = useContext(SlotContext); + return ; +}; + +export default ChooseSlot; diff --git a/packages/rn-declarative/src/components/One/slots/ChooseSlot/IChooseSlot.ts b/packages/rn-declarative/src/components/One/slots/ChooseSlot/IChooseSlot.ts new file mode 100644 index 0000000..836ebd7 --- /dev/null +++ b/packages/rn-declarative/src/components/One/slots/ChooseSlot/IChooseSlot.ts @@ -0,0 +1,12 @@ +import { IChooseFieldProps, IChooseFieldPrivate } from "../../fields/ChooseField"; + +type IChooseBase = IChooseFieldProps & IChooseFieldPrivate; + +/** + * Represents the interface for choosing a time slot. + * @interface + * @extends IChooseBase + */ +export interface IChooseSlot extends IChooseBase { } + +export default IChooseSlot; diff --git a/packages/rn-declarative/src/components/One/slots/ChooseSlot/index.ts b/packages/rn-declarative/src/components/One/slots/ChooseSlot/index.ts new file mode 100644 index 0000000..8467671 --- /dev/null +++ b/packages/rn-declarative/src/components/One/slots/ChooseSlot/index.ts @@ -0,0 +1,3 @@ +export * from './IChooseSlot'; +export * from './ChooseSlot'; +export { default } from './ChooseSlot'; diff --git a/packages/rn-declarative/src/components/One/slots/index.ts b/packages/rn-declarative/src/components/One/slots/index.ts index 16d0e5a..42a74a7 100644 --- a/packages/rn-declarative/src/components/One/slots/index.ts +++ b/packages/rn-declarative/src/components/One/slots/index.ts @@ -12,3 +12,4 @@ export * from './ProgressSlot'; export * from './RatingSlot'; export * from './SliderSlot'; export * from './TimeSlot'; +export * from './ChooseSlot'; diff --git a/packages/rn-declarative/src/index.ts b/packages/rn-declarative/src/index.ts index ea641ef..b735ff2 100644 --- a/packages/rn-declarative/src/index.ts +++ b/packages/rn-declarative/src/index.ts @@ -110,6 +110,7 @@ import { IProgressSlot as IProgressSlotInternal } from './components'; import { IRatingSlot as IRatingSlotInternal } from './components'; import { ISliderSlot as ISliderSlotInternal } from './components'; import { ITimeSlot as ITimeSlotInternal } from './components'; +import { IChooseSlot as IChooseSlotInternal } from './components'; export type ICheckBoxSlot = ICheckBoxSlotInternal; export type IComboSlot = IComboSlotInternal; @@ -126,6 +127,7 @@ export type IProgressSlot = IProgressSlotInternal; export type IRatingSlot = IRatingSlotInternal; export type ISliderSlot = ISliderSlotInternal; export type ITimeSlot = ITimeSlotInternal; +export type IChooseSlot = IChooseSlotInternal; export { randomString } from './utils/randomString'; export { compareFulltext } from './utils/compareFulltext'; diff --git a/packages/rn-declarative/src/model/FieldType.ts b/packages/rn-declarative/src/model/FieldType.ts index b81aab6..af0ee1b 100644 --- a/packages/rn-declarative/src/model/FieldType.ts +++ b/packages/rn-declarative/src/model/FieldType.ts @@ -24,7 +24,7 @@ export enum FieldType { Rating = 'rating-field', Slider = 'slider-field', Time = 'time-field', - + Choose = 'choose-field', }; Object.entries(FieldType).forEach(([key, value]) => { diff --git a/packages/rn-declarative/src/model/IField.ts b/packages/rn-declarative/src/model/IField.ts index a2077d8..d20ca0c 100644 --- a/packages/rn-declarative/src/model/IField.ts +++ b/packages/rn-declarative/src/model/IField.ts @@ -339,6 +339,12 @@ export interface IField { * Компонент отображения else для condition */ conditionElse?: React.ComponentType<{ data: Data; payload: Payload }>; + + /** + * Функция для выбора документа из справочника + * для useSearchModal + */ + choose?: (data: Data, payload: Payload) => (Promise | string | string[] | null); } export default IField; diff --git a/packages/rn-declarative/src/model/TypedField.ts b/packages/rn-declarative/src/model/TypedField.ts index 6d6fd09..7a1bb65 100644 --- a/packages/rn-declarative/src/model/TypedField.ts +++ b/packages/rn-declarative/src/model/TypedField.ts @@ -33,6 +33,7 @@ import { IProgressFieldProps } from '../components/One/fields/ProgressField'; import { IRatingFieldProps } from '../components/One/fields/RatingField'; import { ISliderFieldProps } from '../components/One/fields/SliderField'; import { ITimeFieldProps } from '../components/One/fields/TimeField'; +import { IChooseFieldProps } from '../components/One/fields/ChooseField'; /** * Исключения из правила @@ -107,6 +108,7 @@ type Progress = TypedFieldFactoryShallow< type Rating = TypedFieldFactoryShallow, Data, Payload>; type Slider = TypedFieldFactoryShallow, Data, Payload>; type Time = TypedFieldFactoryShallow, Data, Payload>; +type Choose = TypedFieldFactoryShallow, Data, Payload>; /** @@ -124,6 +126,7 @@ export type TypedFieldRegistry ? Rating : Target extends Slider ? Slider : Target extends Time ? Time + : Target extends Choose ? Choose : Target extends Component ? Component : Target extends Items ? Items : Target extends Radio ? Radio