@flowerforce/flower-react 3.0.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/LICENSE +15 -0
  3. package/README.md +771 -0
  4. package/dist/index.cjs.d.ts +1 -0
  5. package/dist/index.cjs.default.js +1 -0
  6. package/dist/index.cjs.js +1134 -0
  7. package/dist/index.cjs.mjs +2 -0
  8. package/dist/index.esm.d.ts +1 -0
  9. package/dist/index.esm.js +1113 -0
  10. package/dist/src/components/Flower.d.ts +9 -0
  11. package/dist/src/components/FlowerAction.d.ts +4 -0
  12. package/dist/src/components/FlowerComponent.d.ts +4 -0
  13. package/dist/src/components/FlowerField.d.ts +4 -0
  14. package/dist/src/components/FlowerFlow.d.ts +4 -0
  15. package/dist/src/components/FlowerNavigate/WrapperComponent.d.ts +4 -0
  16. package/dist/src/components/FlowerNavigate/index.d.ts +4 -0
  17. package/dist/src/components/FlowerNavigate/useFlowerNavigate.d.ts +7 -0
  18. package/dist/src/components/FlowerNode.d.ts +4 -0
  19. package/dist/src/components/FlowerRoute.d.ts +4 -0
  20. package/dist/src/components/FlowerRule.d.ts +4 -0
  21. package/dist/src/components/FlowerServer.d.ts +4 -0
  22. package/dist/src/components/FlowerStart.d.ts +4 -0
  23. package/dist/src/components/FlowerValue.d.ts +4 -0
  24. package/dist/src/components/types/DefaultNode.d.ts +8 -0
  25. package/dist/src/components/types/FlowerComponent.d.ts +4 -0
  26. package/dist/src/components/types/FlowerField.d.ts +30 -0
  27. package/dist/src/components/types/FlowerFlow.d.ts +4 -0
  28. package/dist/src/components/types/FlowerHooks.d.ts +26 -0
  29. package/dist/src/components/types/FlowerNavigate.d.ts +37 -0
  30. package/dist/src/components/types/FlowerNode.d.ts +4 -0
  31. package/dist/src/components/types/FlowerProvider.d.ts +13 -0
  32. package/dist/src/components/types/FlowerRoute.d.ts +8 -0
  33. package/dist/src/components/types/FlowerRule.d.ts +12 -0
  34. package/dist/src/components/types/FlowerServer.d.ts +7 -0
  35. package/dist/src/components/types/FlowerValue.d.ts +11 -0
  36. package/dist/src/components/useFlower.d.ts +3 -0
  37. package/dist/src/components/useFlowerForm.d.ts +3 -0
  38. package/dist/src/context.d.ts +9 -0
  39. package/dist/src/index.d.ts +20 -0
  40. package/dist/src/provider.d.ts +19 -0
  41. package/dist/src/reducer.d.ts +7 -0
  42. package/dist/src/selectors.d.ts +1377 -0
  43. package/dist/src/utils.d.ts +10 -0
  44. package/package.json +49 -0
@@ -0,0 +1,1113 @@
1
+ import React, { createContext, Component, memo, useRef, useState, useMemo, Children, useEffect, useContext, useCallback, useLayoutEffect } from 'react';
2
+ import _keyBy from 'lodash/keyBy';
3
+ import { CoreUtils, FlowerCoreReducers, FlowerStateUtils, Selectors, Emitter, MatchRules } from '@flowerforce/flower-core';
4
+ import _get from 'lodash/get';
5
+ import { createSlice, configureStore } from '@reduxjs/toolkit';
6
+ import { createSelector } from 'reselect';
7
+ import { createDispatchHook, createSelectorHook, createStoreHook, Provider as Provider$1 } from 'react-redux';
8
+ import debounce from 'lodash/debounce';
9
+
10
+ const _context = /*#__PURE__*/createContext({});
11
+ const context = _context;
12
+ const Provider = _context.Provider;
13
+ const Consumer = _context.Consumer;
14
+
15
+ const convertElements = nodes => {
16
+ const res = CoreUtils.generateNodesForFlowerJson(nodes);
17
+ return res;
18
+ };
19
+
20
+ const flowerReducer = createSlice({
21
+ name: 'flower',
22
+ initialState: {},
23
+ reducers: FlowerCoreReducers
24
+ });
25
+ const {
26
+ actions
27
+ } = flowerReducer;
28
+ const reducerFlower = {
29
+ flower: flowerReducer.reducer
30
+ };
31
+
32
+ const {
33
+ getAllData: mapData
34
+ } = FlowerStateUtils;
35
+ const {
36
+ selectGlobal
37
+ } = Selectors;
38
+ const selectFlower = name => createSelector(selectGlobal, Selectors.selectFlower(name));
39
+ const selectFlowerFormNode = (name, id) => createSelector(selectFlower(name), Selectors.selectFlowerFormNode(id));
40
+ const selectFlowerHistory = name => createSelector(selectFlower(name), Selectors.selectFlowerHistory);
41
+ const makeSelectNodesIds = name => createSelector(selectFlower(name), Selectors.makeSelectNodesIds);
42
+ const makeSelectStartNodeId = name => createSelector(selectFlower(name), Selectors.makeSelectStartNodeId);
43
+ const makeSelectCurrentNodeId = name => createSelector(selectFlower(name), makeSelectStartNodeId(name), Selectors.makeSelectCurrentNodeId);
44
+ const makeSelectPrevNodeRetain = name => createSelector(makeSelectNodesIds(name), selectFlowerHistory(name), makeSelectCurrentNodeId(name), Selectors.makeSelectPrevNodeRetain);
45
+ const makeSelectCurrentNodeDisabled = name => createSelector(makeSelectNodesIds(name), makeSelectCurrentNodeId(name), Selectors.makeSelectCurrentNodeDisabled);
46
+ const getDataByFlow = name => createSelector(selectFlower(name), Selectors.getDataByFlow);
47
+ const getDataFromState = (name, id) => createSelector(getDataByFlow(name), Selectors.getDataFromState(id));
48
+ const makeSelectNodeErrors = (name, currentNodeId) => createSelector(selectFlowerFormNode(name, currentNodeId), Selectors.makeSelectNodeErrors);
49
+ const makeSelectNodeFormTouched = (name, currentNodeId) => createSelector(selectFlowerFormNode(name, currentNodeId), Selectors.makeSelectNodeFormTouched);
50
+ const getAllData = createSelector(selectGlobal, mapData);
51
+ const makeSelectFieldError = (name, id, validate) => createSelector(getAllData, Selectors.makeSelectFieldError(name, id, validate));
52
+ const selectorRulesDisabled = (id, rules, keys, flowName, value, currentNode) => createSelector(getAllData, makeSelectNodeErrors(flowName, currentNode), Selectors.selectorRulesDisabled(id, rules, keys, flowName, value));
53
+
54
+ const reduxContext = /*#__PURE__*/createContext(null);
55
+ const useDispatch = createDispatchHook(reduxContext);
56
+ const useSelector = createSelectorHook(reduxContext);
57
+ const useStore = createStoreHook(reduxContext);
58
+ const store = configureStore({
59
+ reducer: reducerFlower,
60
+ devTools: {
61
+ name: 'flower'
62
+ }
63
+ });
64
+ class FlowerProvider extends Component {
65
+ constructor(props) {
66
+ super(props);
67
+ this.store = store;
68
+ }
69
+ render() {
70
+ const {
71
+ children
72
+ } = this.props;
73
+ return /*#__PURE__*/React.createElement(Provider$1, {
74
+ context: reduxContext,
75
+ store: this.store
76
+ }, children);
77
+ }
78
+ }
79
+
80
+ const FlowerClient = ({
81
+ children,
82
+ name,
83
+ destroyOnUnmount: _destroyOnUnmount = true,
84
+ startId: _startId = null,
85
+ initialData: _initialData = {}
86
+ }) => {
87
+ const flowName = name;
88
+ const dispatch = useDispatch();
89
+ const one = useRef(false);
90
+ const [wsDevtools, setWsDevtools] = useState(global.window && _get(global.window, '__FLOWER_DEVTOOLS_INITIALIZED__', false));
91
+ const nodes = useMemo(() => convertElements(Children.toArray(children)), [children]);
92
+ const nodeById = useMemo(() => _keyBy(Children.toArray(children), 'props.id'), [children]);
93
+ const isInitialized = useSelector(makeSelectStartNodeId(name));
94
+ const history = useSelector(selectFlowerHistory(name));
95
+ const current = useSelector(makeSelectCurrentNodeId(flowName));
96
+ const isDisabled = useSelector(makeSelectCurrentNodeDisabled(flowName));
97
+ const prevFlowerNodeId = useSelector(makeSelectPrevNodeRetain(flowName));
98
+ const store = useStore();
99
+ useEffect(() => {
100
+ if (nodes.length > 0 && one.current === false) {
101
+ one.current = true;
102
+ dispatch(actions.initNodes({
103
+ name: flowName,
104
+ nodes,
105
+ startId: _startId != null ? _startId : '',
106
+ persist: _destroyOnUnmount === false,
107
+ initialData: _initialData
108
+ }));
109
+ }
110
+ }, [dispatch, flowName, nodes, _startId, _initialData, _destroyOnUnmount]);
111
+ useEffect(() => {
112
+ const eventCb = msg => {
113
+ if (msg.source !== 'flower-devtool') return;
114
+ if (msg.action === 'FLOWER_EXTENSION_INIT' || msg.action === 'FLOWER_DEVTOOL_WEB_INIT') {
115
+ setWsDevtools(true);
116
+ }
117
+ if (msg.action === 'SELECTED_NODE' && msg.name === flowName) {
118
+ dispatch(actions.setCurrentNode({
119
+ name: msg.name,
120
+ node: msg.id
121
+ }));
122
+ }
123
+ if (msg.action === 'REPLACE_DATA' && msg.name === flowName) {
124
+ dispatch(actions.replaceData({
125
+ flowName: msg.name,
126
+ value: msg.data
127
+ }));
128
+ }
129
+ if (msg.action === 'ADD_DATA' && msg.name === flowName) {
130
+ dispatch(actions.addData({
131
+ flowName: msg.name,
132
+ value: msg.data
133
+ }));
134
+ }
135
+ };
136
+ if (global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
137
+ Emitter.on('flower-devtool-to-client', eventCb);
138
+ }
139
+ return () => {
140
+ if (global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
141
+ Emitter.off('flower-devtool-to-client', eventCb);
142
+ }
143
+ };
144
+ }, [dispatch, flowName]);
145
+ useEffect(() => () => {
146
+ if (_destroyOnUnmount && one.current === true) {
147
+ one.current = false;
148
+ dispatch(actions.destroy({
149
+ name: flowName
150
+ }));
151
+ }
152
+ }, [dispatch, flowName, _destroyOnUnmount]);
153
+ useEffect(() => {
154
+ if (isInitialized && wsDevtools && global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
155
+ Emitter.emit('flower-devtool-from-client', {
156
+ source: 'flower-client',
157
+ action: 'FLOWER_CLIENT_INIT',
158
+ name: flowName,
159
+ time: new Date(),
160
+ nodeId: isInitialized
161
+ });
162
+ }
163
+ }, [dispatch, flowName, wsDevtools, isInitialized]);
164
+ useEffect(() => {
165
+ if (isInitialized && wsDevtools && global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
166
+ Emitter.emit('flower-devtool-from-client', {
167
+ source: 'flower-client',
168
+ action: 'SET_HISTORY',
169
+ name: flowName,
170
+ history
171
+ });
172
+ }
173
+ }, [dispatch, flowName, history, wsDevtools, isInitialized]);
174
+ useEffect(() => {
175
+ if (!current) return;
176
+ if (!isInitialized) return;
177
+ if (isInitialized && wsDevtools && global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
178
+ Emitter.emit('flower-devtool-from-client', {
179
+ source: 'flower-client',
180
+ action: 'SET_CURRENT',
181
+ name: flowName,
182
+ current
183
+ });
184
+ }
185
+ }, [flowName, current, wsDevtools, isInitialized]);
186
+ useEffect(() => {
187
+ if (!current) return;
188
+ if (!isInitialized) return;
189
+ if (isDisabled) {
190
+ dispatch({
191
+ type: 'flower/next',
192
+ payload: {
193
+ flowName,
194
+ disabled: true
195
+ }
196
+ });
197
+ if (wsDevtools && global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
198
+ Emitter.emit('flower-devtool-from-client', {
199
+ source: 'flower-client',
200
+ action: 'FLOWER_NAVIGATE',
201
+ nodeId: current,
202
+ name: flowName,
203
+ time: new Date(),
204
+ params: {
205
+ action: 'next',
206
+ payload: {
207
+ flowName,
208
+ disabled: true
209
+ }
210
+ }
211
+ });
212
+ }
213
+ return;
214
+ }
215
+ if (wsDevtools && global.window && _get(global.window, '__FLOWER_DEVTOOLS__')) {
216
+ if (isInitialized === current) return;
217
+ Emitter.emit('flower-devtool-from-client', {
218
+ source: 'flower-client',
219
+ action: 'SET_SELECTED',
220
+ nodeId: current,
221
+ name: flowName,
222
+ time: new Date()
223
+ });
224
+ }
225
+ }, [dispatch, flowName, current, isDisabled, store, wsDevtools, isInitialized]);
226
+ const contextValues = useMemo(() => ({
227
+ flowName,
228
+ currentNode: current
229
+ }), [flowName, current]);
230
+ return isInitialized ? ( /*#__PURE__*/React.createElement(Provider, {
231
+ value: contextValues
232
+ }, prevFlowerNodeId !== current && typeof prevFlowerNodeId === 'string' && nodeById[prevFlowerNodeId], !isDisabled && nodeById[current])) : null;
233
+ };
234
+ const component$c = /*#__PURE__*/memo(FlowerClient);
235
+
236
+ const FlowerNode = ({
237
+ children,
238
+ onEnter,
239
+ onExit
240
+ }) => {
241
+ useEffect(() => {
242
+ onEnter == null || onEnter();
243
+ return () => {
244
+ onExit == null || onExit();
245
+ };
246
+ }, [onEnter, onExit]);
247
+ return children;
248
+ };
249
+ const component$b = /*#__PURE__*/memo(FlowerNode);
250
+ component$b.displayName = 'FlowerNode';
251
+
252
+ const FlowAction = ({
253
+ children,
254
+ onEnter,
255
+ onExit
256
+ }) => {
257
+ useEffect(() => {
258
+ onEnter == null || onEnter();
259
+ return () => {
260
+ onExit == null || onExit();
261
+ };
262
+ }, [onEnter, onExit]);
263
+ return children;
264
+ };
265
+ const component$a = /*#__PURE__*/React.memo(FlowAction);
266
+ component$a.displayName = 'FlowerAction';
267
+
268
+ const FlowerServer = ({
269
+ children
270
+ }) => {
271
+ return children;
272
+ };
273
+ const component$9 = /*#__PURE__*/React.memo(FlowerServer);
274
+ component$9.displayName = 'FlowerServer';
275
+
276
+ const FlowerFlow = ({
277
+ children,
278
+ onEnter,
279
+ onExit
280
+ }) => {
281
+ useEffect(() => {
282
+ onEnter == null || onEnter();
283
+ return () => {
284
+ onExit == null || onExit();
285
+ };
286
+ }, [onEnter, onExit]);
287
+ return children;
288
+ };
289
+ const component$8 = /*#__PURE__*/React.memo(FlowerFlow);
290
+ component$8.displayName = 'FlowerFlow';
291
+
292
+ function FlowerStart() {
293
+ const dispatch = useDispatch();
294
+ const one = useRef(false);
295
+ const {
296
+ flowName,
297
+ autostart = true,
298
+ currentNode
299
+ } = useContext(context);
300
+ const startNodeId = useSelector(makeSelectStartNodeId(flowName != null ? flowName : ''));
301
+ useEffect(() => {
302
+ if (startNodeId === currentNode && autostart && one.current === false) {
303
+ one.current = true;
304
+ dispatch({
305
+ type: 'flower/next',
306
+ payload: {
307
+ flowName,
308
+ isStart: true
309
+ }
310
+ });
311
+ }
312
+ }, [dispatch, autostart, startNodeId, currentNode, flowName]);
313
+ return null;
314
+ }
315
+ const component$7 = /*#__PURE__*/React.memo(FlowerStart);
316
+ component$7.displayName = 'FlowerStart';
317
+
318
+ const FlowerRoute = ({
319
+ autostart: _autostart = true,
320
+ children,
321
+ onEnter,
322
+ onExit
323
+ }) => {
324
+ const dispatch = useDispatch();
325
+ const one = useRef(false);
326
+ const {
327
+ flowName
328
+ } = useContext(context);
329
+ useEffect(() => {
330
+ onEnter == null || onEnter();
331
+ return () => {
332
+ onExit == null || onExit();
333
+ };
334
+ }, [onEnter, onExit]);
335
+ useEffect(() => {
336
+ if (_autostart && one.current === false) {
337
+ one.current = true;
338
+ dispatch({
339
+ type: 'flower/next',
340
+ payload: {
341
+ flowName
342
+ }
343
+ });
344
+ }
345
+ }, [dispatch, flowName, _autostart]);
346
+ return children;
347
+ };
348
+ const component$6 = /*#__PURE__*/React.memo(FlowerRoute);
349
+ component$6.displayName = 'FlowerRoute';
350
+
351
+ function _extends() {
352
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
353
+ for (var i = 1; i < arguments.length; i++) {
354
+ var source = arguments[i];
355
+ for (var key in source) {
356
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
357
+ target[key] = source[key];
358
+ }
359
+ }
360
+ }
361
+ return target;
362
+ };
363
+ return _extends.apply(this, arguments);
364
+ }
365
+ function _objectWithoutPropertiesLoose(source, excluded) {
366
+ if (source == null) return {};
367
+ var target = {};
368
+ for (var key in source) {
369
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
370
+ if (excluded.indexOf(key) >= 0) continue;
371
+ target[key] = source[key];
372
+ }
373
+ }
374
+ return target;
375
+ }
376
+
377
+ const FlowerRule = ({
378
+ children,
379
+ rules,
380
+ value,
381
+ alwaysDisplay,
382
+ flowName,
383
+ id,
384
+ onUpdate
385
+ }) => {
386
+ const {
387
+ flowName: flowNameContext,
388
+ currentNode
389
+ } = useContext(context);
390
+ const name = flowName || flowNameContext;
391
+ const keys = MatchRules.utils.getKeys(rules, {
392
+ prefix: name
393
+ });
394
+ const hidden = useSelector(selectorRulesDisabled(id != null ? id : '', rules, keys != null ? keys : [], name != null ? name : '', value, currentNode != null ? currentNode : ''));
395
+ useEffect(() => {
396
+ if (onUpdate) {
397
+ onUpdate(hidden);
398
+ }
399
+ }, [hidden, onUpdate]);
400
+ if (typeof children === 'function') {
401
+ if (alwaysDisplay && hidden) {
402
+ return children({
403
+ hidden
404
+ });
405
+ }
406
+ if (hidden) {
407
+ return undefined;
408
+ }
409
+ return children({});
410
+ }
411
+ if (alwaysDisplay && hidden) {
412
+ return React.Children.map(children, (child, i) => {
413
+ if ( /*#__PURE__*/React.isValidElement(child)) {
414
+ const {
415
+ props,
416
+ type
417
+ } = child;
418
+ const Component = type;
419
+ return Component && /*#__PURE__*/React.createElement(Component, _extends({
420
+ key: i,
421
+ hidden: true
422
+ }, props));
423
+ }
424
+ return child;
425
+ });
426
+ }
427
+ return hidden ? undefined : React.Children.map(children, (child, i) => {
428
+ if ( /*#__PURE__*/React.isValidElement(child)) {
429
+ const {
430
+ props,
431
+ type
432
+ } = child;
433
+ const Component = type;
434
+ return Component && /*#__PURE__*/React.createElement(Component, _extends({
435
+ key: i
436
+ }, props));
437
+ }
438
+ return child;
439
+ });
440
+ };
441
+ const component$5 = /*#__PURE__*/React.memo(FlowerRule);
442
+ component$5.displayName = 'FlowerRule';
443
+
444
+ const _excluded$3 = ["Component", "id", "flowName", "currentNode", "validate", "asyncDebounce", "asyncValidate", "asyncInitialError", "asyncWaitingError", "destroyValue", "onBlur", "hidden", "onUpdate", "defaultValue"];
445
+ function isIntrinsicElement$1(x) {
446
+ return typeof x === 'string';
447
+ }
448
+ function Wrapper$1(_ref) {
449
+ let {
450
+ Component,
451
+ id,
452
+ flowName,
453
+ currentNode,
454
+ validate,
455
+ asyncDebounce = 0,
456
+ asyncValidate,
457
+ asyncInitialError,
458
+ asyncWaitingError,
459
+ destroyValue,
460
+ onBlur = val => null,
461
+ hidden,
462
+ onUpdate,
463
+ defaultValue
464
+ } = _ref,
465
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$3);
466
+ const dispatch = useDispatch();
467
+ const [touched, setTouched] = useState();
468
+ const [customErrors, setCustomErrors] = useState(asyncValidate && [asyncInitialError]);
469
+ const [isValidating, setIsValidating] = useState(undefined);
470
+ const {
471
+ flowNameFromPath = flowName,
472
+ path
473
+ } = useMemo(() => CoreUtils.getPath(id), [id]);
474
+ const value = useSelector(getDataFromState(flowNameFromPath, path));
475
+ const errors = useSelector(makeSelectFieldError(flowName, id, validate), CoreUtils.allEqual);
476
+ const refValue = useRef();
477
+ const one = useRef();
478
+ const validateFn = useCallback(async value => {
479
+ if (asyncWaitingError) {
480
+ setCustomErrors([asyncWaitingError]);
481
+ }
482
+ setIsValidating(true);
483
+ const state = FlowerStateUtils.getAllData(store);
484
+ const res = await asyncValidate(value, state, errors);
485
+ setIsValidating(false);
486
+ setCustomErrors(res);
487
+ }, [asyncWaitingError, errors]);
488
+ const debouncedValidation = useCallback(debounce(validateFn, asyncDebounce), [validateFn]);
489
+ useEffect(() => {
490
+ if (asyncValidate) {
491
+ if (refValue.current === value) return;
492
+ refValue.current = value;
493
+ const hasValue = !MatchRules.utils.isEmpty(value);
494
+ if (!hasValue) {
495
+ setCustomErrors([asyncInitialError]);
496
+ setIsValidating(false);
497
+ return;
498
+ }
499
+ setTouched(true);
500
+ debouncedValidation(value);
501
+ }
502
+ }, [asyncValidate, asyncInitialError, value, debouncedValidation]);
503
+ const touchedForm = useSelector(makeSelectNodeFormTouched(flowName, currentNode));
504
+ const allErrors = useMemo(() => [...errors, ...(customErrors || []).filter(Boolean)], [errors, customErrors]);
505
+ useEffect(() => {
506
+ if (onUpdate) {
507
+ onUpdate(value);
508
+ }
509
+ }, [value, onUpdate]);
510
+ const onChange = useCallback(val => {
511
+ dispatch({
512
+ type: `flower/addDataByPath`,
513
+ payload: {
514
+ flowName: flowNameFromPath,
515
+ id: path,
516
+ value: val
517
+ }
518
+ });
519
+ }, [flowNameFromPath, path, onBlur, dispatch]);
520
+ const onBlurInternal = useCallback(e => {
521
+ setTouched(true);
522
+ onBlur && onBlur(e);
523
+ }, [onBlur]);
524
+ useLayoutEffect(() => {
525
+ dispatch({
526
+ type: 'flower/formAddErrors',
527
+ payload: {
528
+ name: flowName,
529
+ id,
530
+ currentNode,
531
+ errors: allErrors
532
+ }
533
+ });
534
+ }, [id, flowName, allErrors, currentNode]);
535
+ useEffect(() => {
536
+ dispatch({
537
+ type: 'flower/setFormIsValidating',
538
+ payload: {
539
+ name: flowName,
540
+ currentNode,
541
+ isValidating
542
+ }
543
+ });
544
+ }, [flowName, currentNode, isValidating]);
545
+ useLayoutEffect(() => {
546
+ return () => {
547
+ if (destroyValue) {
548
+ dispatch({
549
+ type: `flower/unsetData`,
550
+ payload: {
551
+ flowName: flowNameFromPath,
552
+ id: path
553
+ }
554
+ });
555
+ }
556
+ dispatch({
557
+ type: 'flower/formRemoveErrors',
558
+ payload: {
559
+ name: flowName,
560
+ id,
561
+ currentNode
562
+ }
563
+ });
564
+ };
565
+ }, [destroyValue]);
566
+ useEffect(() => {
567
+ if (defaultValue && !one.current) {
568
+ one.current = true;
569
+ onChange(defaultValue);
570
+ }
571
+ }, [defaultValue, onChange]);
572
+ const isTouched = touched || touchedForm;
573
+ const newProps = useMemo(() => _extends({}, props, {
574
+ id,
575
+ value,
576
+ errors: isTouched && allErrors,
577
+ hasError: isTouched && !!allErrors.length,
578
+ onChange,
579
+ onBlur: onBlurInternal,
580
+ isTouched,
581
+ hidden,
582
+ isValidating
583
+ }), [props, id, value, allErrors, isTouched, onChange, onBlurInternal, hidden, isValidating]);
584
+ if (typeof Component === 'function') {
585
+ return Component(newProps);
586
+ }
587
+ if (isIntrinsicElement$1(Component)) {
588
+ return /*#__PURE__*/React.createElement(Component, _extends({
589
+ id: id
590
+ }, props));
591
+ }
592
+ return Component && /*#__PURE__*/React.createElement(Component, _extends({}, newProps));
593
+ }
594
+ const FlowerField = ({
595
+ id,
596
+ validate,
597
+ asyncValidate,
598
+ asyncDebounce,
599
+ asyncInitialError,
600
+ asyncWaitingError,
601
+ rules,
602
+ alwaysDisplay,
603
+ value,
604
+ children,
605
+ defaultValue,
606
+ destroyValue,
607
+ flowName,
608
+ onUpdate
609
+ }) => {
610
+ const {
611
+ flowName: flowNameContext,
612
+ currentNode
613
+ } = useContext(context);
614
+ const name = flowName || flowNameContext;
615
+ if (typeof children === 'function') {
616
+ return /*#__PURE__*/React.createElement(component$5, {
617
+ alwaysDisplay: alwaysDisplay,
618
+ rules: rules,
619
+ value: value,
620
+ flowName: name,
621
+ id: id
622
+ }, ({
623
+ hidden
624
+ }) => ( /*#__PURE__*/React.createElement(Wrapper$1, {
625
+ hidden: hidden,
626
+ id: id,
627
+ Component: children,
628
+ flowName: name,
629
+ currentNode: currentNode,
630
+ validate: validate,
631
+ asyncValidate: asyncValidate,
632
+ asyncDebounce: asyncDebounce,
633
+ asyncInitialError: asyncInitialError,
634
+ asyncWaitingError: asyncWaitingError,
635
+ destroyValue: destroyValue,
636
+ onUpdate: onUpdate,
637
+ defaultValue: defaultValue
638
+ })));
639
+ }
640
+ return React.Children.map(children, (child, i) => {
641
+ if (! /*#__PURE__*/React.isValidElement(child)) {
642
+ return child;
643
+ }
644
+ const {
645
+ type,
646
+ props
647
+ } = child;
648
+ const Component = type;
649
+ return /*#__PURE__*/React.createElement(component$5, {
650
+ key: i,
651
+ alwaysDisplay: alwaysDisplay,
652
+ rules: rules,
653
+ value: value,
654
+ flowName: name
655
+ }, ({
656
+ hidden
657
+ }) => ( /*#__PURE__*/React.createElement(Wrapper$1, _extends({}, props, {
658
+ hidden: hidden,
659
+ id: id,
660
+ Component: Component,
661
+ flowName: name,
662
+ currentNode: currentNode,
663
+ validate: validate,
664
+ asyncValidate: asyncValidate,
665
+ asyncDebounce: asyncDebounce,
666
+ asyncInitialError: asyncInitialError,
667
+ asyncWaitingError: asyncWaitingError,
668
+ destroyValue: destroyValue,
669
+ onUpdate: onUpdate,
670
+ defaultValue: defaultValue
671
+ }))));
672
+ });
673
+ };
674
+ const component$4 = /*#__PURE__*/React.memo(FlowerField);
675
+ component$4.displayName = 'FlowerField';
676
+
677
+ const _excluded$2 = ["Component", "id", "flowName", "spreadValue", "hidden", "onUpdate"],
678
+ _excluded2 = ["id", "alwaysDisplay", "rules", "value", "Component", "spreadValue", "flowName", "onUpdate"];
679
+ function Wrapper(_ref) {
680
+ let {
681
+ Component,
682
+ id,
683
+ flowName,
684
+ spreadValue,
685
+ hidden,
686
+ onUpdate
687
+ } = _ref,
688
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$2);
689
+ const {
690
+ flowNameFromPath = flowName,
691
+ path
692
+ } = useMemo(() => CoreUtils.getPath(id), [id]);
693
+ const value = useSelector(getDataFromState(flowNameFromPath, path));
694
+ const values = spreadValue && typeof value === 'object' && !Array.isArray(value) ? value : {
695
+ value
696
+ };
697
+ useEffect(() => {
698
+ if (onUpdate) {
699
+ onUpdate(value);
700
+ }
701
+ }, [onUpdate, value]);
702
+ return /*#__PURE__*/React.createElement(Component, _extends({
703
+ id: id
704
+ }, props, {
705
+ flowName: flowName,
706
+ hidden: hidden
707
+ }, values));
708
+ }
709
+ const RenderRules$1 = _ref2 => {
710
+ let {
711
+ id,
712
+ alwaysDisplay,
713
+ rules,
714
+ value,
715
+ Component,
716
+ spreadValue,
717
+ flowName,
718
+ onUpdate
719
+ } = _ref2,
720
+ props = _objectWithoutPropertiesLoose(_ref2, _excluded2);
721
+ return /*#__PURE__*/React.createElement(component$5, {
722
+ alwaysDisplay: alwaysDisplay,
723
+ rules: rules,
724
+ value: value,
725
+ flowName: flowName,
726
+ id: id
727
+ }, ({
728
+ hidden
729
+ }) => ( /*#__PURE__*/React.createElement(Wrapper, _extends({}, props, {
730
+ hidden: hidden,
731
+ id: id,
732
+ Component: Component,
733
+ spreadValue: spreadValue,
734
+ flowName: flowName,
735
+ onUpdate: onUpdate
736
+ }))));
737
+ };
738
+ const FlowerValue = ({
739
+ id: _id = '*',
740
+ rules,
741
+ alwaysDisplay,
742
+ value,
743
+ children,
744
+ spreadValue,
745
+ flowName,
746
+ onUpdate
747
+ }) => {
748
+ const {
749
+ flowName: flowNameContext
750
+ } = useContext(context);
751
+ const name = flowName || flowNameContext;
752
+ if (typeof children === 'function') {
753
+ return /*#__PURE__*/React.createElement(RenderRules$1, {
754
+ id: _id,
755
+ alwaysDisplay: alwaysDisplay,
756
+ rules: rules,
757
+ value: value,
758
+ spreadValue: spreadValue,
759
+ Component: children,
760
+ flowName: name,
761
+ onUpdate: onUpdate
762
+ });
763
+ }
764
+ return React.Children.map(children, (child, i) => {
765
+ if (! /*#__PURE__*/React.isValidElement(child)) return child;
766
+ const {
767
+ type,
768
+ props
769
+ } = child;
770
+ const Component = type;
771
+ return /*#__PURE__*/React.createElement(RenderRules$1, _extends({
772
+ key: i,
773
+ id: _id,
774
+ alwaysDisplay: alwaysDisplay,
775
+ rules: rules,
776
+ value: value,
777
+ spreadValue: spreadValue,
778
+ flowName: name,
779
+ Component: Component
780
+ }, props, {
781
+ onUpdate: onUpdate
782
+ }));
783
+ });
784
+ };
785
+ const component$3 = /*#__PURE__*/React.memo(FlowerValue);
786
+ component$3.displayName = 'FlowerValue';
787
+
788
+ const ACTION_TYPES = {
789
+ back: ['prev', 'prevToNode'],
790
+ reset: ['reset', 'initializeFromNode'],
791
+ jump: ['node', 'node'],
792
+ next: ['next', 'next']
793
+ };
794
+ const PAYLAOAD_KEYS_NEEDED = {
795
+ back: ['node'],
796
+ reset: ['node'],
797
+ jump: ['node', 'history'],
798
+ next: ['node', 'route', 'data']
799
+ };
800
+ const makeActionPayload = (actions, keys) => (flowName, params) => {
801
+ const rest = typeof params === 'string' ? {
802
+ node: params
803
+ } : params;
804
+ const payload = _extends({
805
+ flowName: (params == null ? void 0 : params.flowName) || flowName
806
+ }, Object.fromEntries(Object.entries(rest != null ? rest : {}).filter(([k]) => keys.includes(k))));
807
+ const type = !params || !payload.node ? actions[0] : actions[1];
808
+ return {
809
+ type,
810
+ payload
811
+ };
812
+ };
813
+ const makeActionPayloadOnPrev = makeActionPayload(ACTION_TYPES.back, PAYLAOAD_KEYS_NEEDED.back);
814
+ const makeActionPayloadOnReset = makeActionPayload(ACTION_TYPES.reset, PAYLAOAD_KEYS_NEEDED.reset);
815
+ const makeActionPayloadOnNode = makeActionPayload(ACTION_TYPES.jump, PAYLAOAD_KEYS_NEEDED.jump);
816
+ const makeActionPayloadOnNext = makeActionPayload(ACTION_TYPES.next, PAYLAOAD_KEYS_NEEDED.next);
817
+ const useFlower = ({
818
+ flowName: customFlowName,
819
+ name
820
+ } = {}) => {
821
+ const dispatch = useDispatch();
822
+ const {
823
+ flowName: flowNameDefault
824
+ } = useContext(context);
825
+ const flowName = customFlowName || name || flowNameDefault;
826
+ const nodeId = useSelector(makeSelectCurrentNodeId(flowName != null ? flowName : ''));
827
+ const emitNavigateEvent = useCallback(params => {}, [flowName, nodeId]);
828
+ const next = useCallback(param => {
829
+ const params = typeof param === 'string' ? {
830
+ route: param
831
+ } : {
832
+ data: param
833
+ };
834
+ const {
835
+ type,
836
+ payload
837
+ } = makeActionPayloadOnNext(flowName, params);
838
+ dispatch({
839
+ type: `flower/${type}`,
840
+ payload
841
+ });
842
+ emitNavigateEvent({
843
+ type,
844
+ payload
845
+ });
846
+ }, [dispatch, emitNavigateEvent, flowName]);
847
+ const back = useCallback(param => {
848
+ const {
849
+ type,
850
+ payload
851
+ } = makeActionPayloadOnPrev(flowName, param);
852
+ dispatch({
853
+ type: `flower/${type}`,
854
+ payload
855
+ });
856
+ emitNavigateEvent({
857
+ type,
858
+ payload
859
+ });
860
+ }, [dispatch, emitNavigateEvent, flowName]);
861
+ const reset = useCallback(param => {
862
+ const {
863
+ type,
864
+ payload
865
+ } = makeActionPayloadOnReset(flowName, param);
866
+ dispatch({
867
+ type: `flower/${type}`,
868
+ payload
869
+ });
870
+ emitNavigateEvent({
871
+ type,
872
+ payload
873
+ });
874
+ }, [dispatch, emitNavigateEvent, flowName]);
875
+ const jump = useCallback(param => {
876
+ const {
877
+ type,
878
+ payload
879
+ } = makeActionPayloadOnNode(flowName, param);
880
+ dispatch({
881
+ type: `flower/${type}`,
882
+ payload
883
+ });
884
+ emitNavigateEvent({
885
+ type,
886
+ payload
887
+ });
888
+ }, [dispatch, emitNavigateEvent, flowName]);
889
+ return {
890
+ flowName,
891
+ nodeId,
892
+ next,
893
+ jump,
894
+ back,
895
+ reset
896
+ };
897
+ };
898
+
899
+ const useFlowerNavigate = ({
900
+ flowName,
901
+ action,
902
+ route,
903
+ node
904
+ }) => {
905
+ const {
906
+ flowName: flowNameContext
907
+ } = useContext(context);
908
+ const name = flowName || flowNameContext;
909
+ const {
910
+ next,
911
+ jump,
912
+ back,
913
+ reset
914
+ } = useFlower({
915
+ flowName: name
916
+ });
917
+ const onNavigate = useCallback(() => {
918
+ switch (action) {
919
+ case 'next':
920
+ next(route);
921
+ return;
922
+ case 'jump':
923
+ jump(node);
924
+ return;
925
+ case 'back':
926
+ back(node);
927
+ return;
928
+ case 'reset':
929
+ reset(node);
930
+ return;
931
+ default:
932
+ next();
933
+ return;
934
+ }
935
+ }, [next, jump, back, reset, node, route]);
936
+ return {
937
+ onNavigate,
938
+ flowName
939
+ };
940
+ };
941
+
942
+ const _excluded$1 = ["hidden", "Component", "onNavigate"];
943
+ function isIntrinsicElement(x) {
944
+ return typeof x === 'string';
945
+ }
946
+ function FlowerNavigateWrapper(_ref) {
947
+ let {
948
+ hidden,
949
+ Component,
950
+ onNavigate
951
+ } = _ref,
952
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$1);
953
+ const newProps = useMemo(() => _extends({}, props, {
954
+ hidden,
955
+ onClick: onNavigate
956
+ }), [props, onNavigate]);
957
+ if (typeof Component === 'function') {
958
+ return Component(newProps);
959
+ }
960
+ if (isIntrinsicElement(Component)) {
961
+ return /*#__PURE__*/React.createElement(Component, _extends({}, props, {
962
+ onClick: onNavigate
963
+ }));
964
+ }
965
+ return Component && /*#__PURE__*/React.createElement(Component, _extends({}, newProps));
966
+ }
967
+ const component$2 = /*#__PURE__*/React.memo(FlowerNavigateWrapper);
968
+
969
+ const _excluded = ["alwaysDisplay", "rules", "Component", "flowName", "onNavigate"];
970
+ const RenderRules = _ref => {
971
+ let {
972
+ alwaysDisplay,
973
+ rules,
974
+ Component,
975
+ flowName,
976
+ onNavigate
977
+ } = _ref,
978
+ props = _objectWithoutPropertiesLoose(_ref, _excluded);
979
+ return /*#__PURE__*/React.createElement(component$5, {
980
+ alwaysDisplay: alwaysDisplay,
981
+ rules: rules,
982
+ flowName: flowName
983
+ }, ({
984
+ hidden
985
+ }) => /*#__PURE__*/React.createElement(component$2, _extends({}, props, {
986
+ Component: Component,
987
+ hidden: hidden,
988
+ onNavigate: onNavigate
989
+ })));
990
+ };
991
+ const FlowerNavigate = ({
992
+ children,
993
+ flowName: forceFlowName,
994
+ action,
995
+ route,
996
+ node,
997
+ rules,
998
+ alwaysDisplay
999
+ }) => {
1000
+ const {
1001
+ onNavigate,
1002
+ flowName
1003
+ } = useFlowerNavigate({
1004
+ flowName: forceFlowName,
1005
+ action,
1006
+ route,
1007
+ node
1008
+ });
1009
+ if (typeof children === 'function') {
1010
+ return /*#__PURE__*/React.createElement(RenderRules, {
1011
+ alwaysDisplay: alwaysDisplay,
1012
+ rules: rules,
1013
+ Component: children,
1014
+ flowName: flowName,
1015
+ onNavigate: onNavigate
1016
+ });
1017
+ }
1018
+ return React.Children.map(children, (child, i) => {
1019
+ if (! /*#__PURE__*/React.isValidElement(child)) return child;
1020
+ const {
1021
+ type,
1022
+ props
1023
+ } = child;
1024
+ const Component = type;
1025
+ return /*#__PURE__*/React.createElement(RenderRules, _extends({
1026
+ key: i,
1027
+ alwaysDisplay: alwaysDisplay,
1028
+ rules: rules,
1029
+ Component: Component,
1030
+ flowName: flowName,
1031
+ onNavigate: onNavigate
1032
+ }, props));
1033
+ });
1034
+ };
1035
+ const component$1 = /*#__PURE__*/React.memo(FlowerNavigate);
1036
+ component$1.displayName = 'FlowerNavigate';
1037
+
1038
+ const FlowerComponent = ({
1039
+ children
1040
+ }) => children;
1041
+ const component = /*#__PURE__*/memo(FlowerComponent);
1042
+
1043
+ const useFlowerForm = ({
1044
+ flowName: customFlowName,
1045
+ name
1046
+ } = {}) => {
1047
+ const {
1048
+ flowName: flowNameDefault
1049
+ } = useContext(context);
1050
+ const dispatch = useDispatch();
1051
+ const store = useStore();
1052
+ const flowName = customFlowName || name || flowNameDefault || '';
1053
+ const currentNode = useSelector(makeSelectCurrentNodeId(flowName));
1054
+ const {
1055
+ errors,
1056
+ isValid,
1057
+ touched,
1058
+ isValidating
1059
+ } = useSelector(makeSelectNodeErrors(flowName, currentNode));
1060
+ const getData = useCallback(path => {
1061
+ const {
1062
+ flowNameFromPath = flowName,
1063
+ path: newpath
1064
+ } = CoreUtils.getPath(path);
1065
+ return _get(store.getState(), ['flower', flowNameFromPath, 'data', ...newpath]);
1066
+ }, [store, flowName]);
1067
+ const setData = useCallback((val, path) => {
1068
+ if (path) {
1069
+ const {
1070
+ flowNameFromPath = flowName,
1071
+ path: newpath
1072
+ } = CoreUtils.getPath(path);
1073
+ dispatch(actions.addDataByPath({
1074
+ flowName: flowNameFromPath,
1075
+ id: Array.isArray(newpath) ? newpath : [newpath],
1076
+ value: val
1077
+ }));
1078
+ return;
1079
+ }
1080
+ dispatch(actions.addData({
1081
+ flowName,
1082
+ value: val
1083
+ }));
1084
+ }, [flowName, dispatch]);
1085
+ const unsetData = useCallback(path => {
1086
+ const {
1087
+ flowNameFromPath = flowName,
1088
+ path: newpath
1089
+ } = CoreUtils.getPath(path);
1090
+ dispatch(actions.unsetData({
1091
+ flowName: flowNameFromPath,
1092
+ id: newpath
1093
+ }));
1094
+ }, [flowName, dispatch]);
1095
+ const replaceData = useCallback(val => {
1096
+ dispatch(actions.replaceData({
1097
+ flowName,
1098
+ value: val
1099
+ }));
1100
+ }, [flowName, dispatch]);
1101
+ return {
1102
+ touched,
1103
+ errors,
1104
+ isValid,
1105
+ isValidating,
1106
+ getData,
1107
+ setData,
1108
+ unsetData,
1109
+ replaceData
1110
+ };
1111
+ };
1112
+
1113
+ export { component$c as Flower, component$a as FlowerAction, component as FlowerComponent, context as FlowerContext, Consumer as FlowerContextConsumer, Provider as FlowerContextProvider, component$4 as FlowerField, component$8 as FlowerFlow, component$1 as FlowerNavigate, component$b as FlowerNode, FlowerProvider, component$6 as FlowerRoute, component$5 as FlowerRule, component$9 as FlowerServer, component$7 as FlowerStart, component$3 as FlowerValue, getDataByFlow, useFlower, useFlowerForm, useSelector };