@flowerforce/flower-react 3.7.1 → 4.0.1-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/CHANGELOG.md +12 -0
- package/README.md +290 -199
- package/dist/index.cjs.js +427 -670
- package/dist/index.esm.js +409 -654
- package/dist/src/components/Flower.d.ts +3 -15
- package/dist/src/components/FlowerAction.d.ts +2 -3
- package/dist/src/components/FlowerComponent.d.ts +2 -4
- package/dist/src/components/FlowerFlow.d.ts +2 -3
- package/dist/src/components/FlowerNavigate/FlowerNavigate.d.ts +3 -0
- package/dist/src/components/FlowerNavigate/WrapperComponent.d.ts +3 -3
- package/dist/src/components/FlowerNavigate/index.d.ts +2 -4
- package/dist/src/components/FlowerNavigate/useFlowerNavigate.d.ts +1 -1
- package/dist/src/components/FlowerNode.d.ts +2 -3
- package/dist/src/components/FlowerRoute.d.ts +2 -3
- package/dist/src/components/FlowerServer.d.ts +2 -3
- package/dist/src/components/FlowerStart.d.ts +3 -4
- package/dist/src/components/hooks/eventsHandlers.d.ts +5 -0
- package/dist/src/components/hooks/index.d.ts +5 -0
- package/dist/src/components/hooks/types/index.d.ts +29 -0
- package/dist/src/components/hooks/useBrowserNavigationSync.d.ts +12 -0
- package/dist/src/components/hooks/useDestroyFlow.d.ts +2 -0
- package/dist/src/components/hooks/useInitDevtools.d.ts +2 -0
- package/dist/src/components/hooks/useInitNodes.d.ts +2 -0
- package/dist/src/components/hooks/useSelectorsClient.d.ts +6 -0
- package/dist/src/components/index.d.ts +10 -0
- package/dist/src/components/{useFlower.d.ts → useFlower/index.d.ts} +2 -3
- package/dist/src/components/useFlower/utils.d.ts +22 -0
- package/dist/src/features/index.d.ts +2 -0
- package/dist/src/features/reducer/flowerReducer.d.ts +7 -0
- package/dist/src/{selectors.d.ts → features/selectors/selectors.d.ts} +669 -383
- package/dist/src/index.d.ts +6 -33
- package/dist/src/provider/createSliceWithFlower.d.ts +2 -0
- package/dist/src/provider/createStoreWithFlower.d.ts +8 -0
- package/dist/src/provider/index.d.ts +3 -0
- package/dist/src/provider/provider.d.ts +7 -0
- package/dist/src/types/FlowContext.d.ts +6 -0
- package/dist/src/types/Flower.d.ts +15 -0
- package/dist/src/types/FlowerHooks.d.ts +27 -0
- package/dist/src/{components/types → types}/FlowerProvider.d.ts +3 -3
- package/dist/src/types/index.d.ts +10 -0
- package/dist/src/types/middlewares.d.ts +16 -0
- package/dist/src/types/utilsTypes.d.ts +4 -0
- package/dist/src/utils.d.ts +2 -10
- package/package.json +15 -7
- package/dist/src/components/FlowerField.d.ts +0 -4
- package/dist/src/components/FlowerRule.d.ts +0 -4
- package/dist/src/components/FlowerValue.d.ts +0 -4
- package/dist/src/components/types/FlowerField.d.ts +0 -124
- package/dist/src/components/types/FlowerHooks.d.ts +0 -72
- package/dist/src/components/types/FlowerRule.d.ts +0 -35
- package/dist/src/components/types/FlowerValue.d.ts +0 -33
- package/dist/src/components/useFlowerForm.d.ts +0 -26
- package/dist/src/context.d.ts +0 -10
- package/dist/src/provider.d.ts +0 -25
- package/dist/src/reducer.d.ts +0 -7
- /package/dist/src/{components/types → types}/DefaultNode.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerComponent.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerFlow.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerNavigate.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerNode.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerRoute.d.ts +0 -0
- /package/dist/src/{components/types → types}/FlowerServer.d.ts +0 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
<a alt="Flower logo" href="https://flowerjs.it/" target="_blank" rel="noreferrer"><img src="https://flowerjs.it/_next/static/media/flower-logo.bb32f863.svg" width="50"></a>
|
4
4
|
|
5
|
-
Flower React is a front-end development library built on top of Flower Core, specifically designed for React applications.
|
5
|
+
Flower React is a front-end development library built on top of Flower Core, specifically designed for React applications.
|
6
|
+
It seamlessly integrates Flower's powerful capabilities into React projects, providing a user-friendly interface to create, modify, and monitor workflows.
|
6
7
|
|
7
8
|
For more info [flowerjs.it/](https://flowerjs.it/)
|
8
9
|
|
@@ -15,8 +16,6 @@ For more info [flowerjs.it/](https://flowerjs.it/)
|
|
15
16
|
- **State Management**: Built-in state management to keep track of workflow changes and updates.
|
16
17
|
- **Event System**: Customizable event handling to respond to user interactions and changes within the workflow.
|
17
18
|
- **Serialization**: Convert workflows to JSON for easy storage and retrieval. (only server side flow)
|
18
|
-
- **Validation**: Ensure workflows follow predefined rules and constraints to maintain integrity.
|
19
|
-
- **Form Validation**: Built-in functionalities to validate form inputs within nodes, ensuring data integrity and correctness.
|
20
19
|
- **History Management**: Internal management of flow history, tracking node traversal and changes for debugging and visualization purposes.
|
21
20
|
|
22
21
|
### Installation
|
@@ -45,7 +44,11 @@ yarn add @flowerforce/flower-react
|
|
45
44
|
|
46
45
|
## Configuration
|
47
46
|
|
48
|
-
|
47
|
+
|
48
|
+
Flower React works with redux global state.
|
49
|
+
|
50
|
+
If you starts an application with Flower React from scratch, you need to wrap your application with **FlowerProvider**
|
51
|
+
The **FlowerProvider** component wraps the entire application, providing a global redux context to manage the application flow.
|
49
52
|
|
50
53
|
```jsx
|
51
54
|
import React from 'react'
|
@@ -59,7 +62,69 @@ function Root() {
|
|
59
62
|
)
|
60
63
|
}
|
61
64
|
```
|
62
|
-
|
65
|
+
|
66
|
+
If your application is already built with redux as global state manager, you can use differents approaches:
|
67
|
+
|
68
|
+
- Separates Providers
|
69
|
+
|
70
|
+
In this case, you need to wrap your application with the **FlowerProvider** component in addition to the classic Redux provider.
|
71
|
+
The order of providers is not relevant, since their redux contexts are different.
|
72
|
+
n.b.: FlowerProvider generates a store instance with `FlowerData slice` from `flower-react-form`
|
73
|
+
|
74
|
+
```jsx
|
75
|
+
import React from 'react'
|
76
|
+
import { Provider } from 'react-redux'
|
77
|
+
import { yourStore } from 'yourStore'
|
78
|
+
import { FlowerProvider } from '@flowerforce/flower-react'
|
79
|
+
|
80
|
+
function Root() {
|
81
|
+
return (
|
82
|
+
<Provider store={yourStore}>
|
83
|
+
<FlowerProvider>
|
84
|
+
<App />
|
85
|
+
</FlowerProvider>
|
86
|
+
</Provider>
|
87
|
+
)
|
88
|
+
}
|
89
|
+
```
|
90
|
+
|
91
|
+
- Single Provider
|
92
|
+
|
93
|
+
For this scenario, we provides ***createStoreWithFlower***
|
94
|
+
This functions takes a `configureStoreOptions` object (same as createStore from redux) and an optional `middlewaresBlacklist`, since flower inject automatically some middlewares in its store.
|
95
|
+
To generate slices fully compatible, you can use ***createSliceWithFlower***, a function same as `createSlice` from redux.
|
96
|
+
Let's see the needed configuration
|
97
|
+
```jsx
|
98
|
+
import React from 'react'
|
99
|
+
import { Provider } from 'react-redux'
|
100
|
+
import { FormProvider, createStoreWithFlower, createSliceWithFlower } from '@flowerforce/flower-react'
|
101
|
+
|
102
|
+
const myStoreWithFlower = createSliceWithFlower({
|
103
|
+
name: 'myStore',
|
104
|
+
initialData: {},
|
105
|
+
reducers: {
|
106
|
+
add: (state) => {
|
107
|
+
state.count += 1
|
108
|
+
}
|
109
|
+
}
|
110
|
+
})
|
111
|
+
|
112
|
+
const storeWithFlower = createStoreWithFlower({
|
113
|
+
reducer: {
|
114
|
+
myStore: myStoreWithFlower.reducer,
|
115
|
+
}
|
116
|
+
})
|
117
|
+
|
118
|
+
function Root() {
|
119
|
+
return (
|
120
|
+
<Provider store={storeWithFlower}>
|
121
|
+
<App />
|
122
|
+
</Provider>
|
123
|
+
)
|
124
|
+
}
|
125
|
+
```
|
126
|
+
|
127
|
+
In this scenario, we need a single provider, so we use the default redux provider
|
63
128
|
|
64
129
|
## How to use
|
65
130
|
|
@@ -110,10 +175,9 @@ Edit on [codesandbox/](https://codesandbox.io/p/sandbox/flower-react-example-1-9
|
|
110
175
|
|
111
176
|
This prop allows you to configure the following fields:
|
112
177
|
|
113
|
-
1) `startId`: string
|
114
|
-
2) `current`: string
|
115
|
-
3) `history`: string[]
|
116
|
-
|
178
|
+
1) `startId`: string - First node of current flow
|
179
|
+
2) `current`: string - Current node of current flow
|
180
|
+
3) `history`: string[] - History of nodes in current flow
|
117
181
|
|
118
182
|
|
119
183
|
### Navigate with routes
|
@@ -210,64 +274,6 @@ export const Page = () => {
|
|
210
274
|
|
211
275
|
Edit on [codesandbox/](https://codesandbox.io/p/sandbox/flower-react-example-1-forked-5c4rs4)
|
212
276
|
|
213
|
-
### Basic WRITE | READ State
|
214
|
-
|
215
|
-
To modify the internal state of Flower, besides passing initialData as a prop, we can always modify and read the state through the components **FlowerField** and **FlowerValue**.
|
216
|
-
|
217
|
-
_FlowerField_ pass two props, onChange and value, to properly modify and read the value from the state of Flower.
|
218
|
-
_FlowerValue_ pass value, to properly read the value from the state of Flower.
|
219
|
-
|
220
|
-
Here's an example of how it works:
|
221
|
-
|
222
|
-
```jsx
|
223
|
-
import React from 'react'
|
224
|
-
import {
|
225
|
-
Flower,
|
226
|
-
FlowerRoute,
|
227
|
-
FlowerNavigate,
|
228
|
-
FlowerNode,
|
229
|
-
FlowerField,
|
230
|
-
FlowerValue
|
231
|
-
} from '@flowerforce/flower-react'
|
232
|
-
|
233
|
-
export const Page = () => {
|
234
|
-
return (
|
235
|
-
<Flower name="demo">
|
236
|
-
<FlowerNode
|
237
|
-
id="step1"
|
238
|
-
to={{
|
239
|
-
step3: {
|
240
|
-
rules: { $and: [{ skipStep2: { $eq: true } }] }
|
241
|
-
},
|
242
|
-
step2: null
|
243
|
-
}}
|
244
|
-
>
|
245
|
-
...
|
246
|
-
|
247
|
-
<FlowerField id="skipStep2">
|
248
|
-
{({ onChange, value }) => <input type="checkbox" checked={value} onChange={e => onChange(e.target.checked)} />}
|
249
|
-
</FlowerField>
|
250
|
-
|
251
|
-
<FlowerNavigate action="next">
|
252
|
-
<button>click me to go next</button>
|
253
|
-
</FlowerNavigate>
|
254
|
-
</FlowerNode>
|
255
|
-
|
256
|
-
<FlowerNode id="step2">...</FlowerNode>
|
257
|
-
|
258
|
-
<FlowerNode id="step3">
|
259
|
-
<FlowerValue id="enableFinal">
|
260
|
-
{({ value }) => <span>skipStep2: {String(!!value)}</span>}
|
261
|
-
</FlowerValue>
|
262
|
-
</FlowerNode>
|
263
|
-
|
264
|
-
</Flower>
|
265
|
-
)
|
266
|
-
}
|
267
|
-
|
268
|
-
```
|
269
|
-
|
270
|
-
Edit on [codesandbox/](https://codesandbox.io/p/sandbox/flower-react-example-3-forked-r3hgnj)
|
271
277
|
|
272
278
|
### Action Node
|
273
279
|
|
@@ -424,7 +430,7 @@ export const Page = () => {
|
|
424
430
|
|
425
431
|
Edit on [codesandbox/](https://codesandbox.io/p/sandbox/flower-react-example-1-forked-6wj3l9)
|
426
432
|
|
427
|
-
#### External use
|
433
|
+
#### External use of useFlower
|
428
434
|
|
429
435
|
```jsx
|
430
436
|
import React from 'react'
|
@@ -499,11 +505,211 @@ export const Page = () => {
|
|
499
505
|
}
|
500
506
|
```
|
501
507
|
|
502
|
-
## Form
|
503
508
|
|
504
|
-
Flower enables the quick creation of forms.
|
505
509
|
|
506
|
-
|
510
|
+
|
511
|
+
## Operators Rules
|
512
|
+
|
513
|
+
The "rules" in Flower are used to define conditions and conditional behaviors within the workflow. These rules allow to dynamically change the display or behavior of certain fields or components based on specific conditions.
|
514
|
+
|
515
|
+
The rules schema follows the MongoDB style, below is the list of available operators:
|
516
|
+
|
517
|
+
- $exists: Checks if a value exists or not.
|
518
|
+
- $eq: Checks if two values are equal.
|
519
|
+
- $ne: Checks if two values are not equal.
|
520
|
+
- $gt: Checks if the first value is greater than the second.
|
521
|
+
- $gte: Checks if the first value is greater than or equal to the second.
|
522
|
+
- $lt: Checks if the first value is less than the second.
|
523
|
+
- $lte: Checks if the first value is less than or equal to the second.
|
524
|
+
- $strGt: Checks if the length of a string is greater than the specified value.
|
525
|
+
- $strGte: Checks if the length of a string is greater than or equal to the specified value.
|
526
|
+
- $strLt: Checks if the length of a string is less than the specified value.
|
527
|
+
- $strLte: Checks if the length of a string is less than or equal to the specified value.
|
528
|
+
- $in: Checks if a value is present in a given array.
|
529
|
+
- $nin: Checks if a value is not present in a given array.
|
530
|
+
- $all: Checks if all values are present in a given array.
|
531
|
+
- $regex: Checks if a string matches a regular expression.
|
532
|
+
|
533
|
+
### Examples
|
534
|
+
|
535
|
+
Rules in $and | $or
|
536
|
+
|
537
|
+
```jsx
|
538
|
+
<FlowerNode id="node"
|
539
|
+
to={{
|
540
|
+
node2: {
|
541
|
+
rules: { $and: [
|
542
|
+
{ myValue: { $exists: true } },
|
543
|
+
{ myValue: { $strGt: 6 } }
|
544
|
+
|
545
|
+
]}
|
546
|
+
}
|
547
|
+
}}>
|
548
|
+
...
|
549
|
+
</Flower>
|
550
|
+
|
551
|
+
<FlowerNode id="node"
|
552
|
+
to={{
|
553
|
+
node2: {
|
554
|
+
rules: { $or: [
|
555
|
+
{ myValue: { $exists: false } },
|
556
|
+
{ myValue: { $strGt: 6 } }
|
557
|
+
|
558
|
+
]}
|
559
|
+
}
|
560
|
+
}}>
|
561
|
+
...
|
562
|
+
</Flower>
|
563
|
+
|
564
|
+
```
|
565
|
+
|
566
|
+
Compare state value, use '$ref:'
|
567
|
+
|
568
|
+
```jsx
|
569
|
+
<Flower name="demo" initialData={{ myValue1: 'test', myValue2: 'test2' }}>
|
570
|
+
<FlowerNode id="node"
|
571
|
+
to={{
|
572
|
+
node2: {
|
573
|
+
rules: [
|
574
|
+
{ myValue1: { $eq: '$ref:myValue2' } }
|
575
|
+
]}
|
576
|
+
}}>
|
577
|
+
...
|
578
|
+
</Flower>
|
579
|
+
```
|
580
|
+
|
581
|
+
## Display Rules
|
582
|
+
|
583
|
+
Showing or Hiding Fields: You can use rules to show or hide specific fields based on user choices. For example, hiding a "Buttons" unless the user selects a certain option.
|
584
|
+
|
585
|
+
We can use the FlowerRule component to hide a part of the UI according to certain rules.
|
586
|
+
|
587
|
+
If the "alwaysDisplay" property is passed, however, the component will not be automatically hidden, but a "hidden" property will be provided when the rules are not met.
|
588
|
+
|
589
|
+
### Example
|
590
|
+
|
591
|
+
```jsx
|
592
|
+
import React from 'react'
|
593
|
+
import {
|
594
|
+
Flower,
|
595
|
+
FlowerRoute,
|
596
|
+
FlowerNode,
|
597
|
+
FlowerRule,
|
598
|
+
FlowerNavigate
|
599
|
+
} from '@flowerforce/flower-react'
|
600
|
+
|
601
|
+
export const Page = () => {
|
602
|
+
return (
|
603
|
+
<Flower name="demo" initialData={{ enableNav: true }}>
|
604
|
+
<FlowerNode id="step1" to={{ step2: null }}>
|
605
|
+
...
|
606
|
+
{/* show / hidden based on rule */}
|
607
|
+
<FlowerRule rules={{ enableNav: { $eq: true } }}>
|
608
|
+
<p>Buttons nav are enabled</p>
|
609
|
+
</FlowerRule>
|
610
|
+
{/* always visible component, hidden prop is true when rule is not matched */}
|
611
|
+
<FlowerNavigate
|
612
|
+
action="next"
|
613
|
+
rules={{ enableNav: { $eq: true } }}
|
614
|
+
alwaysDisplay
|
615
|
+
>
|
616
|
+
{({ onClick, hidden }) => (
|
617
|
+
<button disabled={hidden} onClick={onClick}>
|
618
|
+
Next →
|
619
|
+
</button>
|
620
|
+
)}
|
621
|
+
</FlowerNavigate>
|
622
|
+
{/* visible only when rule is matched */}
|
623
|
+
<FlowerNavigate action="reset" rules={{ enableNav: { $eq: true } }}>
|
624
|
+
<button>Reset</button>
|
625
|
+
</FlowerNavigate>
|
626
|
+
</FlowerNode>
|
627
|
+
...
|
628
|
+
</Flower>
|
629
|
+
)
|
630
|
+
}
|
631
|
+
```
|
632
|
+
|
633
|
+
Edit on [codesandbox/](https://codesandbox.io/p/sandbox/flower-react-example-1-forked-sfn6ml)
|
634
|
+
|
635
|
+
|
636
|
+
# FlowerForm Integrations
|
637
|
+
Next to FlowerReact, we find FlowerForm, another library designed to manage data and forms independently from the flow process.
|
638
|
+
(add link to new form documentation)
|
639
|
+
|
640
|
+
### Basic WRITE | READ State - move this in form
|
641
|
+
|
642
|
+
To modify the internal state of Flower, besides passing initialData as a prop, we can always modify and read the state through the components **FlowerField** and **FlowerValue**.
|
643
|
+
|
644
|
+
N.B.: We must use FlowerField component provided by `@flowerforce/flower-react-form`
|
645
|
+
N.B.: We must use FlowerValue component provided by `@flowerforce/flower-react-shared`
|
646
|
+
|
647
|
+
|
648
|
+
_FlowerField_ pass two props, onChange and value, to properly modify and read the value from the state of Flower.
|
649
|
+
_FlowerValue_ pass value, to properly read the value from the state of Flower.
|
650
|
+
|
651
|
+
Here's an example of how it works:
|
652
|
+
|
653
|
+
```jsx
|
654
|
+
import React from 'react'
|
655
|
+
import {
|
656
|
+
Flower,
|
657
|
+
FlowerRoute,
|
658
|
+
FlowerNavigate,
|
659
|
+
FlowerNode
|
660
|
+
} from '@flowerforce/flower-react'
|
661
|
+
|
662
|
+
import {
|
663
|
+
FlowerField,
|
664
|
+
} from '@flowerforce/flower-react-form'
|
665
|
+
|
666
|
+
import { FlowerValue } from '@flowerforce/flower-react-shared'
|
667
|
+
|
668
|
+
|
669
|
+
export const Page = () => {
|
670
|
+
return (
|
671
|
+
<Flower name="demo">
|
672
|
+
<FlowerNode
|
673
|
+
id="step1"
|
674
|
+
to={{
|
675
|
+
step3: {
|
676
|
+
rules: { $and: [{ skipStep2: { $eq: true } }] }
|
677
|
+
},
|
678
|
+
step2: null
|
679
|
+
}}
|
680
|
+
>
|
681
|
+
...
|
682
|
+
|
683
|
+
<FlowerField id="skipStep2">
|
684
|
+
{({ onChange, value }) => <input type="checkbox" checked={value} onChange={e => onChange(e.target.checked)} />}
|
685
|
+
</FlowerField>
|
686
|
+
|
687
|
+
<FlowerNavigate action="next">
|
688
|
+
<button>click me to go next</button>
|
689
|
+
</FlowerNavigate>
|
690
|
+
</FlowerNode>
|
691
|
+
|
692
|
+
<FlowerNode id="step2">...</FlowerNode>
|
693
|
+
|
694
|
+
<FlowerNode id="step3">
|
695
|
+
<FlowerValue id="enableFinal">
|
696
|
+
{({ value }) => <span>skipStep2: {String(!!value)}</span>}
|
697
|
+
</FlowerValue>
|
698
|
+
</FlowerNode>
|
699
|
+
|
700
|
+
</Flower>
|
701
|
+
)
|
702
|
+
}
|
703
|
+
|
704
|
+
```
|
705
|
+
|
706
|
+
Edit on [codesandbox/](https://codesandbox.io/p/sandbox/flower-react-example-3-forked-r3hgnj)
|
707
|
+
|
708
|
+
## Form - move this in form
|
709
|
+
N.B.: `@flowerforce/flower-react-form` provides its own provider `FormProvider` and an equivalent of `<Flower>` component called `<FlowerForm>`
|
710
|
+
In this case we don't need to use it as form components reads from <Flower> context and mantains consistency between flowname and formname
|
711
|
+
|
712
|
+
For more info [flowerjs.it/flower-react-form](https://flowerjs.it/flower-react-form) /// we must generate pages in website for specific documentation
|
507
713
|
|
508
714
|
### Basic Usage
|
509
715
|
|
@@ -512,11 +718,15 @@ import {
|
|
512
718
|
Flower,
|
513
719
|
FlowerNavigate,
|
514
720
|
FlowerNode,
|
515
|
-
FlowerField,
|
516
721
|
FlowerAction,
|
517
|
-
useFlower
|
518
|
-
useFlowerForm
|
722
|
+
useFlower
|
519
723
|
} from '@flowerforce/flower-react'
|
724
|
+
|
725
|
+
import {
|
726
|
+
FlowerField,
|
727
|
+
useFlowerForm
|
728
|
+
} from '@flowerforce/flower-react-form'
|
729
|
+
|
520
730
|
import { useEffect } from 'react'
|
521
731
|
import './styles.css'
|
522
732
|
|
@@ -610,7 +820,7 @@ export default function App() {
|
|
610
820
|
|
611
821
|
<FlowerNavigate
|
612
822
|
action="next"
|
613
|
-
rules={{ $and: [{ '$
|
823
|
+
rules={{ $and: [{ '$data.isValid': { $eq: true } }] }}
|
614
824
|
alwaysDisplay
|
615
825
|
>
|
616
826
|
{({ onClick, hidden }) => (
|
@@ -656,130 +866,6 @@ export default function App() {
|
|
656
866
|
|
657
867
|
Edit on [codesandbox/](https://codesandbox.io/p/sandbox/flower-react-example-1-forked-2f43gh)
|
658
868
|
|
659
|
-
## Operators Rules
|
660
|
-
|
661
|
-
The "rules" in Flower are used to define conditions and conditional behaviors within the workflow. These rules allow to dynamically change the display or behavior of certain fields or components based on specific conditions.
|
662
|
-
|
663
|
-
The rules schema follows the MongoDB style, below is the list of available operators:
|
664
|
-
|
665
|
-
- $exists: Checks if a value exists or not.
|
666
|
-
- $eq: Checks if two values are equal.
|
667
|
-
- $ne: Checks if two values are not equal.
|
668
|
-
- $gt: Checks if the first value is greater than the second.
|
669
|
-
- $gte: Checks if the first value is greater than or equal to the second.
|
670
|
-
- $lt: Checks if the first value is less than the second.
|
671
|
-
- $lte: Checks if the first value is less than or equal to the second.
|
672
|
-
- $strGt: Checks if the length of a string is greater than the specified value.
|
673
|
-
- $strGte: Checks if the length of a string is greater than or equal to the specified value.
|
674
|
-
- $strLt: Checks if the length of a string is less than the specified value.
|
675
|
-
- $strLte: Checks if the length of a string is less than or equal to the specified value.
|
676
|
-
- $in: Checks if a value is present in a given array.
|
677
|
-
- $nin: Checks if a value is not present in a given array.
|
678
|
-
- $all: Checks if all values are present in a given array.
|
679
|
-
- $regex: Checks if a string matches a regular expression.
|
680
|
-
|
681
|
-
### Examples
|
682
|
-
|
683
|
-
Rules in $and | $or
|
684
|
-
|
685
|
-
```jsx
|
686
|
-
<FlowerNode id="node"
|
687
|
-
to={{
|
688
|
-
node2: {
|
689
|
-
rules: { $and: [
|
690
|
-
{ myValue: { $exists: true } },
|
691
|
-
{ myValue: { $strGt: 6 } }
|
692
|
-
|
693
|
-
]}
|
694
|
-
}
|
695
|
-
}}>
|
696
|
-
...
|
697
|
-
</Flower>
|
698
|
-
|
699
|
-
<FlowerNode id="node"
|
700
|
-
to={{
|
701
|
-
node2: {
|
702
|
-
rules: { $or: [
|
703
|
-
{ myValue: { $exists: false } },
|
704
|
-
{ myValue: { $strGt: 6 } }
|
705
|
-
|
706
|
-
]}
|
707
|
-
}
|
708
|
-
}}>
|
709
|
-
...
|
710
|
-
</Flower>
|
711
|
-
|
712
|
-
```
|
713
|
-
|
714
|
-
Compare state value, use '$ref:'
|
715
|
-
|
716
|
-
```jsx
|
717
|
-
<Flower name="demo" initialData={{ myValue1: 'test', myValue2: 'test2' }}>
|
718
|
-
<FlowerNode id="node"
|
719
|
-
to={{
|
720
|
-
node2: {
|
721
|
-
rules: [
|
722
|
-
{ myValue1: { $eq: '$ref:myValue2' } }
|
723
|
-
]}
|
724
|
-
}}>
|
725
|
-
...
|
726
|
-
</Flower>
|
727
|
-
```
|
728
|
-
|
729
|
-
## Display Rules
|
730
|
-
|
731
|
-
Showing or Hiding Fields: You can use rules to show or hide specific fields based on user choices. For example, hiding a "Buttons" unless the user selects a certain option.
|
732
|
-
|
733
|
-
We can use the FlowerRule component to hide a part of the UI according to certain rules.
|
734
|
-
|
735
|
-
If the "alwaysDisplay" property is passed, however, the component will not be automatically hidden, but a "hidden" property will be provided when the rules are not met.
|
736
|
-
|
737
|
-
### Example
|
738
|
-
|
739
|
-
```jsx
|
740
|
-
import React from 'react'
|
741
|
-
import {
|
742
|
-
Flower,
|
743
|
-
FlowerRoute,
|
744
|
-
FlowerNode,
|
745
|
-
FlowerRule,
|
746
|
-
FlowerNavigate
|
747
|
-
} from '@flowerforce/flower-react'
|
748
|
-
|
749
|
-
export const Page = () => {
|
750
|
-
return (
|
751
|
-
<Flower name="demo" initialData={{ enableNav: true }}>
|
752
|
-
<FlowerNode id="step1" to={{ step2: null }}>
|
753
|
-
...
|
754
|
-
{/* show / hidden based on rule */}
|
755
|
-
<FlowerRule rules={{ enableNav: { $eq: true } }}>
|
756
|
-
<p>Buttons nav are enabled</p>
|
757
|
-
</FlowerRule>
|
758
|
-
{/* always visible component, hidden prop is true when rule is not matched */}
|
759
|
-
<FlowerNavigate
|
760
|
-
action="next"
|
761
|
-
rules={{ enableNav: { $eq: true } }}
|
762
|
-
alwaysDisplay
|
763
|
-
>
|
764
|
-
{({ onClick, hidden }) => (
|
765
|
-
<button disabled={hidden} onClick={onClick}>
|
766
|
-
Next →
|
767
|
-
</button>
|
768
|
-
)}
|
769
|
-
</FlowerNavigate>
|
770
|
-
{/* visible only when rule is matched */}
|
771
|
-
<FlowerNavigate action="reset" rules={{ enableNav: { $eq: true } }}>
|
772
|
-
<button>Reset</button>
|
773
|
-
</FlowerNavigate>
|
774
|
-
</FlowerNode>
|
775
|
-
...
|
776
|
-
</Flower>
|
777
|
-
)
|
778
|
-
}
|
779
|
-
```
|
780
|
-
|
781
|
-
Edit on [codesandbox/](https://codesandbox.io/p/sandbox/flower-react-example-1-forked-sfn6ml)
|
782
|
-
|
783
869
|
|
784
870
|
# Debugging Your Flower Application with @flowerforce/devtool
|
785
871
|
To enhance the debugging process of your Flower application, we offer a specialized library named @flowerforce/devtool. This tool is designed to provide a more convenient and powerful debugging experience.
|
@@ -927,3 +1013,8 @@ In any case, there is a JSON schema that will guide you in writing the file asso
|
|
927
1013
|
# Documentation
|
928
1014
|
|
929
1015
|
The Flower React docs are published at [flowerjs.it/](https://flowerjs.it)
|
1016
|
+
|
1017
|
+
|
1018
|
+
|
1019
|
+
|
1020
|
+
|