@flowerforce/flower-react 3.1.1-beta.1 → 3.1.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
- import React, { createContext, Component, memo, useRef, useState, useMemo, Children, useEffect, useContext, useCallback, useLayoutEffect } from 'react';
1
+ import React, { createContext, PureComponent, memo, useRef, useState, useMemo, Children, useEffect, useContext, useCallback, useLayoutEffect } from 'react';
2
2
  import _keyBy from 'lodash/keyBy';
3
- import { CoreUtils, FlowerCoreReducers, FlowerStateUtils, Selectors, Emitter, MatchRules } from '@flowerforce/flower-core';
3
+ import { CoreUtils, FlowerCoreReducers, FlowerStateUtils, Selectors, devtoolState, Emitter, MatchRules } from '@flowerforce/flower-core';
4
4
  import _get from 'lodash/get';
5
5
  import { createSlice, configureStore } from '@reduxjs/toolkit';
6
6
  import { createSelector } from 'reselect';
@@ -12,6 +12,7 @@ const context = _context;
12
12
  const Provider = _context.Provider;
13
13
  const Consumer = _context.Consumer;
14
14
 
15
+ // eslint-disable-next-line import/prefer-default-export
15
16
  const convertElements = nodes => {
16
17
  const res = CoreUtils.generateNodesForFlowerJson(nodes);
17
18
  return res;
@@ -43,7 +44,9 @@ const makeSelectStartNodeId = name => createSelector(selectFlower(name), Selecto
43
44
  const makeSelectCurrentNodeId = name => createSelector(selectFlower(name), makeSelectStartNodeId(name), Selectors.makeSelectCurrentNodeId);
44
45
  const makeSelectPrevNodeRetain = name => createSelector(makeSelectNodesIds(name), selectFlowerHistory(name), makeSelectCurrentNodeId(name), Selectors.makeSelectPrevNodeRetain);
45
46
  const makeSelectCurrentNodeDisabled = name => createSelector(makeSelectNodesIds(name), makeSelectCurrentNodeId(name), Selectors.makeSelectCurrentNodeDisabled);
47
+ // dati nel flow selezionato
46
48
  const getDataByFlow = name => createSelector(selectFlower(name), Selectors.getDataByFlow);
49
+ // selettore per recuperare i dati di un flow specifico e id specifico
47
50
  const getDataFromState = (name, id) => createSelector(getDataByFlow(name), Selectors.getDataFromState(id));
48
51
  const makeSelectNodeErrors = (name, currentNodeId) => createSelector(selectFlowerFormNode(name, currentNodeId), Selectors.makeSelectNodeErrors);
49
52
  const makeSelectNodeFormTouched = (name, currentNodeId) => createSelector(selectFlowerFormNode(name, currentNodeId), Selectors.makeSelectNodeFormTouched);
@@ -51,6 +54,7 @@ const getAllData = createSelector(selectGlobal, mapData);
51
54
  const makeSelectFieldError = (name, id, validate) => createSelector(getAllData, Selectors.makeSelectFieldError(name, id, validate));
52
55
  const selectorRulesDisabled = (id, rules, keys, flowName, value, currentNode) => createSelector(getAllData, makeSelectNodeErrors(flowName, currentNode), Selectors.selectorRulesDisabled(id, rules, keys, flowName, value));
53
56
 
57
+ //TODO check reduxContext type due to remove all any types
54
58
  const reduxContext = /*#__PURE__*/createContext(null);
55
59
  const useDispatch = createDispatchHook(reduxContext);
56
60
  const useSelector = createSelectorHook(reduxContext);
@@ -63,11 +67,11 @@ const store = ({
63
67
  name: 'flower'
64
68
  } : false
65
69
  });
66
- class FlowerProvider extends Component {
70
+ class FlowerProvider extends PureComponent {
67
71
  constructor(props) {
68
72
  super(props);
69
73
  this.store = store({
70
- enableDevtool: props.enableDevtool
74
+ enableDevtool: props.enableReduxDevtool
71
75
  });
72
76
  }
73
77
  render() {
@@ -81,6 +85,11 @@ class FlowerProvider extends Component {
81
85
  }
82
86
  }
83
87
 
88
+ /* eslint-disable no-undef */
89
+ /* eslint-disable no-underscore-dangle */
90
+ /**
91
+ * FlowerClient
92
+ */
84
93
  const FlowerClient = ({
85
94
  children,
86
95
  name,
@@ -91,7 +100,9 @@ const FlowerClient = ({
91
100
  const flowName = name;
92
101
  const dispatch = useDispatch();
93
102
  const one = useRef(false);
94
- const [wsDevtools, setWsDevtools] = useState(global.window && _get(global.window, '__FLOWER_DEVTOOLS_INITIALIZED__', false));
103
+ const [wsDevtools, setWsDevtools] = useState(devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS_INITIALIZED__', false));
104
+ // TODO rivedere il giro, potremmo fare le trasformazioni in CoreUtils.generateNodesForFlowerJson
105
+ // eslint-disable-next-line react-hooks/exhaustive-deps, max-len
95
106
  const nodes = useMemo(() => convertElements(Children.toArray(children)), [children]);
96
107
  const nodeById = useMemo(() => _keyBy(Children.toArray(children), 'props.id'), [children]);
97
108
  const isInitialized = useSelector(makeSelectStartNodeId(name));
@@ -105,6 +116,7 @@ const FlowerClient = ({
105
116
  one.current = true;
106
117
  dispatch(actions.initNodes({
107
118
  name: flowName,
119
+ // @ts-expect-error FIX ME
108
120
  nodes,
109
121
  startId: _startId != null ? _startId : '',
110
122
  persist: _destroyOnUnmount === false,
@@ -113,6 +125,7 @@ const FlowerClient = ({
113
125
  }
114
126
  }, [dispatch, flowName, nodes, _startId, _initialData, _destroyOnUnmount]);
115
127
  useEffect(() => {
128
+ /* istanbul ignore next */
116
129
  const eventCb = msg => {
117
130
  if (msg.source !== 'flower-devtool') return;
118
131
  if (msg.action === 'FLOWER_EXTENSION_INIT' || msg.action === 'FLOWER_DEVTOOL_WEB_INIT') {
@@ -137,16 +150,19 @@ const FlowerClient = ({
137
150
  }));
138
151
  }
139
152
  };
140
- if (global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
153
+ /* istanbul ignore next */
154
+ if (devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS__')) {
141
155
  Emitter.on('flower-devtool-to-client', eventCb);
142
156
  }
143
157
  return () => {
144
- if (global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
158
+ /* istanbul ignore next */
159
+ if (devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS__')) {
145
160
  Emitter.off('flower-devtool-to-client', eventCb);
146
161
  }
147
162
  };
148
163
  }, [dispatch, flowName]);
149
164
  useEffect(() => () => {
165
+ // unmount function
150
166
  if (_destroyOnUnmount && one.current === true) {
151
167
  one.current = false;
152
168
  dispatch(actions.destroy({
@@ -155,7 +171,8 @@ const FlowerClient = ({
155
171
  }
156
172
  }, [dispatch, flowName, _destroyOnUnmount]);
157
173
  useEffect(() => {
158
- if (isInitialized && wsDevtools && global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
174
+ /* istanbul ignore next */
175
+ if (isInitialized && wsDevtools && devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS__')) {
159
176
  Emitter.emit('flower-devtool-from-client', {
160
177
  source: 'flower-client',
161
178
  action: 'FLOWER_CLIENT_INIT',
@@ -167,7 +184,8 @@ const FlowerClient = ({
167
184
  }
168
185
  }, [dispatch, flowName, wsDevtools, isInitialized, store]);
169
186
  useEffect(() => {
170
- if (isInitialized && wsDevtools && global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
187
+ /* istanbul ignore next */
188
+ if (isInitialized && wsDevtools && devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS__')) {
171
189
  Emitter.emit('flower-devtool-from-client', {
172
190
  source: 'flower-client',
173
191
  action: 'SET_HISTORY',
@@ -178,8 +196,10 @@ const FlowerClient = ({
178
196
  }, [dispatch, flowName, history, wsDevtools, isInitialized]);
179
197
  useEffect(() => {
180
198
  if (!current) return;
199
+ /* istanbul ignore next */
181
200
  if (!isInitialized) return;
182
- if (isInitialized && wsDevtools && global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
201
+ /* istanbul ignore next */
202
+ if (isInitialized && wsDevtools && devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS__')) {
183
203
  Emitter.emit('flower-devtool-from-client', {
184
204
  source: 'flower-client',
185
205
  action: 'SET_CURRENT',
@@ -190,6 +210,7 @@ const FlowerClient = ({
190
210
  }, [flowName, current, wsDevtools, isInitialized]);
191
211
  useEffect(() => {
192
212
  if (!current) return;
213
+ /* istanbul ignore next */
193
214
  if (!isInitialized) return;
194
215
  if (isDisabled) {
195
216
  dispatch({
@@ -199,7 +220,9 @@ const FlowerClient = ({
199
220
  disabled: true
200
221
  }
201
222
  });
202
- if (wsDevtools && global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
223
+ // eslint-disable-next-line no-underscore-dangle, no-undef
224
+ /* istanbul ignore next */
225
+ if (wsDevtools && devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS__')) {
203
226
  Emitter.emit('flower-devtool-from-client', {
204
227
  source: 'flower-client',
205
228
  action: 'FLOWER_NAVIGATE',
@@ -217,8 +240,10 @@ const FlowerClient = ({
217
240
  }
218
241
  return;
219
242
  }
220
- if (wsDevtools && global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
221
- if (isInitialized === current) return;
243
+ // eslint-disable-next-line no-underscore-dangle, no-undef
244
+ /* istanbul ignore next */
245
+ if (wsDevtools && devtoolState && _get(devtoolState, '__FLOWER_DEVTOOLS__')) {
246
+ if (isInitialized === current) return; // salto il primo evento
222
247
  Emitter.emit('flower-devtool-from-client', {
223
248
  source: 'flower-client',
224
249
  action: 'SET_SELECTED',
@@ -314,6 +339,15 @@ function FlowerStart() {
314
339
  isStart: true
315
340
  }
316
341
  });
342
+ // if (global.window
343
+ // // eslint-disable-next-line no-underscore-dangle, no-undef
344
+ // && global.window.__FLOWER_DEVTOOLS__ && global.window.__FLOWER_DEVTOOLS__AUTO) {
345
+ // Emitter.emit('flower-devtool-from-client', {
346
+ // source: 'flower-client',
347
+ // action: 'START_FLOWER',
348
+ // name: flowName,
349
+ // });
350
+ // }
317
351
  }
318
352
  }, [dispatch, autostart, startNodeId, currentNode, flowName]);
319
353
  return null;
@@ -415,6 +449,7 @@ const FlowerRule = ({
415
449
  type
416
450
  } = child;
417
451
  const Component = type;
452
+ // eslint-disable-next-line react/jsx-props-no-spreading
418
453
  return Component && /*#__PURE__*/React.createElement(Component, _extends({
419
454
  key: i,
420
455
  hidden: true
@@ -430,6 +465,7 @@ const FlowerRule = ({
430
465
  type
431
466
  } = child;
432
467
  const Component = type;
468
+ // eslint-disable-next-line react/jsx-props-no-spreading
433
469
  return Component && /*#__PURE__*/React.createElement(Component, _extends({
434
470
  key: i
435
471
  }, props));
@@ -444,6 +480,7 @@ const _excluded$3 = ["Component", "id", "flowName", "currentNode", "validate", "
444
480
  function isIntrinsicElement$1(x) {
445
481
  return typeof x === 'string';
446
482
  }
483
+ //TODO make types for wrapper function props
447
484
  function Wrapper$1(_ref) {
448
485
  let {
449
486
  Component,
@@ -542,6 +579,7 @@ function Wrapper$1(_ref) {
542
579
  });
543
580
  }, [flowName, currentNode, isValidating]);
544
581
  useLayoutEffect(() => {
582
+ // destroy
545
583
  return () => {
546
584
  if (destroyValue) {
547
585
  dispatch({
@@ -583,6 +621,8 @@ function Wrapper$1(_ref) {
583
621
  if (typeof Component === 'function') {
584
622
  return Component(newProps);
585
623
  }
624
+ // TODO si arriva in questa condizione quando si passa un componente primitivo es. div
625
+ // in questo caso non posso props custom di flower
586
626
  if (isIntrinsicElement$1(Component)) {
587
627
  return /*#__PURE__*/React.createElement(Component, _extends({
588
628
  id: id
@@ -675,6 +715,7 @@ component$4.displayName = 'FlowerField';
675
715
 
676
716
  const _excluded$2 = ["Component", "id", "flowName", "spreadValue", "hidden", "onUpdate"],
677
717
  _excluded2 = ["id", "alwaysDisplay", "rules", "value", "Component", "spreadValue", "flowName", "onUpdate"];
718
+ //TODO make types for wrapper function
678
719
  function Wrapper(_ref) {
679
720
  let {
680
721
  Component,
@@ -767,6 +808,7 @@ const FlowerValue = ({
767
808
  props
768
809
  } = child;
769
810
  const Component = type;
811
+ // eslint-disable-next-line react/jsx-props-no-spreading
770
812
  return /*#__PURE__*/React.createElement(RenderRules$1, _extends({
771
813
  key: i,
772
814
  id: _id,
@@ -816,6 +858,24 @@ const makeActionPayloadOnReset = makeActionPayload(ACTION_TYPES.reset, PAYLAOAD_
816
858
  const makeActionPayloadOnNode = makeActionPayload(ACTION_TYPES.jump, PAYLAOAD_KEYS_NEEDED.jump);
817
859
  const makeActionPayloadOnNext = makeActionPayload(ACTION_TYPES.next, PAYLAOAD_KEYS_NEEDED.next);
818
860
  const makeActionPayloadOnRestart = makeActionPayload(ACTION_TYPES.restart, PAYLAOAD_KEYS_NEEDED.restart);
861
+ /** This hook allows you to read flow informations, such as the flowName and ID of the current node.
862
+ *
863
+ * It also exposes all the functions to navigate within the flow:
864
+ *
865
+ * - next
866
+ *
867
+ * - back
868
+ *
869
+ * - jump
870
+ *
871
+ * - reset
872
+ *
873
+ * - restart
874
+ *
875
+ * @param {string} flowName - first optional parameter
876
+ *
877
+ * @param {string} name - optional parameter, if flowName exist, name is not used
878
+ */
819
879
  const useFlower = ({
820
880
  flowName: customFlowName,
821
881
  name
@@ -827,8 +887,13 @@ const useFlower = ({
827
887
  } = useContext(context);
828
888
  const flowName = customFlowName || name || flowNameDefault;
829
889
  const nodeId = useSelector(makeSelectCurrentNodeId(flowName != null ? flowName : ''));
830
- const emitNavigateEvent = useCallback(params => {
831
- if (_get(global.window, '__FLOWER_DEVTOOLS__')) {
890
+ const startId = useSelector(makeSelectStartNodeId(flowName != null ? flowName : ''));
891
+ const emitNavigateEvent = useCallback(
892
+ //TODO check this function is needed
893
+ params => {
894
+ /* istanbul ignore next */
895
+ // eslint-disable-next-line no-underscore-dangle, no-undef
896
+ if (_get(devtoolState, '__FLOWER_DEVTOOLS__')) {
832
897
  Emitter.emit('flower-devtool-from-client', {
833
898
  source: 'flower-client',
834
899
  action: 'FLOWER_NAVIGATE',
@@ -922,6 +987,7 @@ const useFlower = ({
922
987
  return {
923
988
  flowName,
924
989
  nodeId,
990
+ startId,
925
991
  next,
926
992
  jump,
927
993
  back,
@@ -930,6 +996,28 @@ const useFlower = ({
930
996
  };
931
997
  };
932
998
 
999
+ /* eslint-disable */
1000
+ // {
1001
+ // flowName?: string | undefined;
1002
+ // action?: 'next' | 'back' | 'reset' | 'jump';
1003
+ // } & (
1004
+ // | {
1005
+ // node?: undefined;
1006
+ // route?: Route;
1007
+ // }
1008
+ // | {
1009
+ // node?: RoutePrev;
1010
+ // route?: undefined;
1011
+ // }
1012
+ // | {
1013
+ // node?: RouteReset;
1014
+ // route?: undefined;
1015
+ // }
1016
+ // | {
1017
+ // node?: RouteNode;
1018
+ // route?: undefined;
1019
+ // }
1020
+ // );
933
1021
  const useFlowerNavigate = ({
934
1022
  flowName,
935
1023
  action,
@@ -981,6 +1069,7 @@ const _excluded$1 = ["hidden", "Component", "onNavigate"];
981
1069
  function isIntrinsicElement(x) {
982
1070
  return typeof x === 'string';
983
1071
  }
1072
+ //TODO type FlowerNavigateWrapper props
984
1073
  function FlowerNavigateWrapper(_ref) {
985
1074
  let {
986
1075
  hidden,
@@ -995,16 +1084,22 @@ function FlowerNavigateWrapper(_ref) {
995
1084
  if (typeof Component === 'function') {
996
1085
  return Component(newProps);
997
1086
  }
1087
+ // TODO si arriva in questa condizione quando si passa un componente primitivo es. div
1088
+ // in questo caso non posso props custom di flower
998
1089
  if (isIntrinsicElement(Component)) {
999
1090
  return /*#__PURE__*/React.createElement(Component, _extends({}, props, {
1000
1091
  onClick: onNavigate
1001
1092
  }));
1002
1093
  }
1094
+ // TODO in questa condizione si arriva se nel progetto si utilizza Vite, in questo caso i componenti non sono Function ma Object,
1095
+ // oppure nel caso di un testo semplice come children di questo componente
1096
+ /* istanbul ignore next */
1003
1097
  return Component && /*#__PURE__*/React.createElement(Component, _extends({}, newProps));
1004
1098
  }
1005
1099
  const component$2 = /*#__PURE__*/React.memo(FlowerNavigateWrapper);
1006
1100
 
1007
1101
  const _excluded = ["alwaysDisplay", "rules", "Component", "flowName", "onNavigate"];
1102
+ //TODO type RenderRules props
1008
1103
  const RenderRules = _ref => {
1009
1104
  let {
1010
1105
  alwaysDisplay,
@@ -1060,6 +1155,7 @@ const FlowerNavigate = ({
1060
1155
  props
1061
1156
  } = child;
1062
1157
  const Component = type;
1158
+ // eslint-disable-next-line react/jsx-props-no-spreading
1063
1159
  return /*#__PURE__*/React.createElement(RenderRules, _extends({
1064
1160
  key: i,
1065
1161
  alwaysDisplay: alwaysDisplay,
@@ -1078,6 +1174,23 @@ const FlowerComponent = ({
1078
1174
  }) => children;
1079
1175
  const component = /*#__PURE__*/memo(FlowerComponent);
1080
1176
 
1177
+ /** This hook allows you to manage and retrieve information about Forms.
1178
+ *
1179
+ * It exposes details regarding the form's state and a set of methods for reading and writing within it:
1180
+ *
1181
+ * - getData
1182
+ *
1183
+ * - setData
1184
+ *
1185
+ * - unSetData
1186
+ *
1187
+ * - replaceData
1188
+ *
1189
+ * @param {string} flowName - first optional parameter
1190
+ *
1191
+ * @param {string} name - optional parameter, if flowName exist, name is not used
1192
+ *
1193
+ */
1081
1194
  const useFlowerForm = ({
1082
1195
  flowName: customFlowName,
1083
1196
  name
@@ -1,8 +1,25 @@
1
1
  export type FlowerNodeDefaultProps = {
2
+ /** Unique identifier for the node inside the Flow */
2
3
  id: string;
4
+ /** An object containing the informations about the node's links.
5
+ *
6
+ * Example: to={{ step2: { rules: { $and: [{ name: { $eq: 'John' } }] } } }}
7
+ *
8
+ * In that case, the FlowerNode is linked to the node with the ID 'step2'
9
+ *
10
+ * You can move from the current node to the step2 node only if the rules are satisfied
11
+ *
12
+ * Set it to null when you don't have rules
13
+ *
14
+ * Example: to={{ step2: null}
15
+ */
3
16
  to?: Record<string, any>;
17
+ /** The children of the FlowerNode */
4
18
  children?: React.ReactNode;
19
+ /** The function executed when you enter into this FlowerNode */
5
20
  onEnter?: () => void;
21
+ /** The function executed when you leave this FlowerNode */
6
22
  onExit?: () => void;
23
+ /** When set to true, the FlowerNode is ignored and skipped */
7
24
  disabled?: boolean;
8
25
  };
@@ -1,4 +1,6 @@
1
1
  export type FlowerComponentProps = {
2
+ /** The name of the component */
2
3
  name: string;
4
+ /** The component's children */
3
5
  children: React.ReactNode;
4
6
  };
@@ -1,30 +1,108 @@
1
1
  import { FunctionRule, RulesObject } from '@flowerforce/flower-core';
2
2
  export type FlowerFieldProps<T extends Record<string, any> = Record<string, any>> = {
3
+ /** The path to the value you want to read from the flow's data
4
+ *
5
+ * Example: id="loginForm.name"
6
+ *
7
+ * The FlowerField component reads the value of the key "name" of the loginForm object in the flow's data
8
+ */
3
9
  id?: string;
10
+ /** The FlowerField's children */
4
11
  children: React.ReactNode | ((props: {
12
+ /** The string passed to the "id" FlowerField's prop */
5
13
  id: string;
14
+ /** The value found at the "id" key in the flow data
15
+ *
16
+ * Example: id="loginForm.name"
17
+ *
18
+ * This parameter will hold the value found at the key 'name' of the loginForm object in the flow's data.
19
+ */
6
20
  value: any;
21
+ /** An array of strings containing error messages associated with validation rules that are not satisfied. */
7
22
  errors: undefined | string[];
23
+ /** This parameter will notify you when there are validation errors. */
8
24
  hasError: undefined | boolean;
25
+ /** Use this function to write a new value at the "id" key
26
+ *
27
+ * Example: id="loginForm.name"
28
+ *
29
+ * onChange("John") will write "John" at the key 'name' of the loginForm object in the flow's data.
30
+ */
9
31
  onChange: (props: any) => void;
32
+ /** The function executed to test all the validation rules*/
10
33
  onBlur: () => void;
34
+ /** This parameter will notify you whether the form field has been touched */
11
35
  isTouched: boolean;
36
+ /** true when some of the display rules are not satisfied, and you have passed true to the "alwaysDisplay" FlowerField's prop*/
12
37
  hidden: boolean;
38
+ /** true when you have an async validation in progress */
13
39
  isValidating: boolean | undefined;
14
40
  }) => React.ReactNode | React.ReactElement | undefined);
41
+ /**The validation rules for that field
42
+ *
43
+ * Example: validate={[
44
+ *
45
+ * {
46
+ * rules: {
47
+ * $self: {
48
+ * $regex:
49
+ * '^([A-Z]{6}[0-9LMNPQRSTUV]{2}[ABCDEHLMPRST]{1}[0-9LMNPQRSTUV]{2}[A-Z]{1}[0-9LMNPQRSTUV]{3}[A-Z]{1})$|([0-9]{11})$',
50
+ * },
51
+ * },
52
+ * message: 'Value not valid',
53
+ * },
54
+ * {
55
+ * // Don't use promises
56
+ * rules: (data)=> {
57
+ * return data.name === 'Andrea'
58
+ * },
59
+ * message: 'Value not valid',
60
+ * }
61
+ * ]}
62
+ *
63
+ * For every rule you can pass an error message, that Flower returns when that condition is note satisfied
64
+ */
15
65
  validate?: Record<string, any>[] | string[];
66
+ /** A function to perform an async validation */
16
67
  asyncValidate?: (value: any, data?: Record<string, any>, errors?: undefined | string[]) => string[] | undefined | Promise<string[]> | {
17
68
  message: string;
18
69
  }[] | boolean | Promise<boolean>;
70
+ /** Use this to set a debounce for the async validation
71
+ *
72
+ * The default value is 0
73
+ */
19
74
  asyncDebounce?: number;
75
+ /** The initial error message when you have an async validation
76
+ *
77
+ * The default value is undefined
78
+ */
20
79
  asyncInitialError?: string;
80
+ /** The message that the FlowerField returns while validating*/
21
81
  asyncWaitingError?: string;
82
+ /** An object containing the display rules of that component. When the conditions are not satisfied, the children is hidden.
83
+ *
84
+ * Example: rules={{ $and: [{ name: { $exist: true } }] }}
85
+ */
22
86
  rules?: RulesObject<T> | FunctionRule;
87
+ /** The name of the flow from which read the data
88
+ *
89
+ * - note: the default value is the name of the flow where the component is used
90
+ */
23
91
  flowName?: string;
92
+ /** Initial value field */
24
93
  defaultValue?: unknown;
25
94
  destroyValue?: boolean;
26
95
  value?: any;
96
+ /** When set to true, the children is shown even if the rules are not satisfied
97
+ *
98
+ * The FlowerField returns the boolean variable "hidden" to notify you if the conditions are satisfied or not
99
+ */
27
100
  alwaysDisplay?: boolean;
101
+ /** The function executed when the value found at the path passed to the "id" prop changes */
28
102
  onUpdate?: (value: any) => void;
103
+ /** The function executed at the "onBlur" event, for example for Input components
104
+ *
105
+ * The onBlur function will test all the validation rules
106
+ */
29
107
  onBlur?: (e: any) => void;
30
108
  };
@@ -1,4 +1,14 @@
1
1
  import { FlowerNodeDefaultProps } from './DefaultNode';
2
2
  export type FlowerFlowProps = FlowerNodeDefaultProps & {
3
+ /** A Flower node is visible only when is the current node in the navigation history of the flow.
4
+ *
5
+ * By setting this prop to true, you have the ability to view this node even when it is not the current node.
6
+ *
7
+ * This can only be set to true for FlowerNode and FlowerFlow components.
8
+ *
9
+ * An example use case is when transitioning from a FlowerNode containing a particular screen to an action node.
10
+ *
11
+ * The node with retain set to true will continue to be displayed until a new FlowerNode or FlowerFlow is added to the history
12
+ * */
3
13
  retain?: boolean;
4
14
  };
@@ -3,25 +3,48 @@ export type UseFlowerProps = {
3
3
  [x in 'name' | 'flowName']?: string;
4
4
  };
5
5
  export type UseFlowerForm = (options?: UseFlowerProps) => {
6
+ /** This value is set to true when the form has been touched at least once. */
6
7
  touched: boolean;
8
+ /** An object containing all the form errors */
7
9
  errors: Record<string, any>;
10
+ /** This value is set to true when all the validation rules are satisfied and the form is valid*/
8
11
  isValid: boolean;
12
+ /** This value is set to true during asynchronous validation.*/
9
13
  isValidating: boolean | undefined;
14
+ /** Use this function to read values from the flow's data. */
10
15
  getData: (path?: string) => any;
11
- setData: (value: any, path?: string) => void;
12
- unsetData: (path: string) => void;
16
+ /** Use this function to set values in the flow's data. */
17
+ setData: (
18
+ /** The value that you want to set */
19
+ value: any,
20
+ /** Specify the target path to set the value*/
21
+ path?: string) => void;
22
+ /** Use this function to unset values in the flow's data. */
23
+ unsetData: (
24
+ /** Specify the target path to the value tha you want to unset*/
25
+ path: string) => void;
26
+ /** Use this function to replace a value in the flow's data. */
13
27
  replaceData: (value: any) => void;
14
28
  };
15
29
  type useFlowerActions = {
30
+ /** Use this function to move to the next node inside the flow*/
16
31
  next: (payload?: Route) => void;
32
+ /**Use this function to move to the previous node inside the flow*/
17
33
  back: (payload?: RoutePrev) => void;
34
+ /**Use this function to return to the first node and restore history */
18
35
  reset: (payload?: RouteReset) => void;
36
+ /**Use this function to move to a specific node*/
19
37
  jump: (payload: RouteNode) => void;
38
+ /**Use this function to reset the flow data and history */
20
39
  restart: (payload?: RouteRestart) => void;
21
40
  };
22
41
  export type UseFlower = (options?: UseFlowerProps) => useFlowerActions & {
42
+ /**The flow in which the hook is used.*/
23
43
  flowName?: string;
44
+ /**Current node id*/
24
45
  nodeId: string;
46
+ /**Initial start node id*/
47
+ startId: string;
25
48
  };
26
49
  export type NavigateFunctionParams = string | Record<string, any>;
27
50
  export {};
@@ -3,6 +3,10 @@ export type Route = string | Record<string, any>;
3
3
  export type RouteNode = string | {
4
4
  node: string;
5
5
  flowName?: string;
6
+ /**
7
+ * The flow's history on server component
8
+ * @experimental
9
+ */
6
10
  history?: string[];
7
11
  };
8
12
  export type RouteRestart = string | {
@@ -19,9 +23,19 @@ export type RoutePrev = string | {
19
23
  flowName?: string;
20
24
  };
21
25
  export type FlowerNavigateProps = {
26
+ /** The name of the flow from which read the data
27
+ *
28
+ * - note: the default value is the name of the flow where the component is used
29
+ */
22
30
  flowName?: string | undefined;
31
+ /** The FlowerNavigate's children */
23
32
  children: React.ReactNode | ((props: Record<string, any>) => React.ReactNode | React.ReactElement | undefined);
33
+ /** An object containing the display rules of that component. When the conditions are not satisfied, the children is hidden. */
24
34
  rules?: RulesObject<Record<string, any>> | Record<string, RulesObject<any>>;
35
+ /** When set to true, the children is shown even if the rules are not satisfied
36
+ *
37
+ * The FlowerValue returns the boolean variable "hidden" to notify you if the conditions are satisfied or not
38
+ */
25
39
  alwaysDisplay?: boolean;
26
40
  } & ({
27
41
  action?: 'next';
@@ -1,4 +1,14 @@
1
1
  import { FlowerNodeDefaultProps } from './DefaultNode';
2
2
  export type FlowerNodeProps = FlowerNodeDefaultProps & {
3
+ /** A Flower node is visible only when is the current node in the navigation history of the flow.
4
+ *
5
+ * By setting this prop to true, you have the ability to view this node even when it is not the current node.
6
+ *
7
+ * This can only be set to true for FlowerNode and FlowerFlow components.
8
+ *
9
+ * An example use case is when transitioning from a FlowerNode containing a particular screen to an action node.
10
+ *
11
+ * The node with retain set to true will continue to be displayed until a new FlowerNode or FlowerFlow is added to the history
12
+ * */
3
13
  retain?: boolean;
4
14
  };
@@ -1,8 +1,25 @@
1
1
  export type FlowerRouteProps = {
2
+ /** Unique identifier for the node inside the Flow */
2
3
  id: string;
4
+ /** TODO document what this props does */
3
5
  autostart?: boolean;
6
+ /** An object containing the informations about the node's links.
7
+ *
8
+ * Example: to={{ step2: { rules: { $and: [{ name: { $eq: 'John' } }] } } }}
9
+ *
10
+ * In that case, the FlowerRoute is linked to the node with the ID 'step2'
11
+ *
12
+ * You can move from the current node to the step2 node only if the rules are satisfied
13
+ *
14
+ * Set it to null when you don't have rules
15
+ *
16
+ * Example: to={{ step2: null}
17
+ */
4
18
  to?: Record<string, any>;
19
+ /** The children of the FlowerRoute */
5
20
  children?: React.ReactNode;
21
+ /** The function executed when you enter into this FlowerRoute */
6
22
  onEnter?: () => void;
23
+ /** The function executed when you leave this FlowerRoute */
7
24
  onExit?: () => void;
8
25
  };