@modular-component/with-conditional-render 0.1.7 → 0.2.1
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 +19 -0
- package/README.md +73 -38
- package/dist/index.d.ts +9 -46
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -29
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +36 -68
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @modular-component/with-conditional-render
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 09b9673: Update readmes
|
|
8
|
+
- Updated dependencies [09b9673]
|
|
9
|
+
- @modular-component/core@0.2.1
|
|
10
|
+
|
|
11
|
+
## 0.2.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 83d453f: Rework API for better TypeScript performance and improved DX
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [83d453f]
|
|
20
|
+
- @modular-component/core@0.2.0
|
|
21
|
+
|
|
3
22
|
## 0.1.7
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,50 +1,85 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @modular-component/with-conditional-render
|
|
2
2
|
|
|
3
3
|
Provides three stages that allow conditional rendering in `ModularComponent`s:
|
|
4
4
|
|
|
5
|
-
- `
|
|
5
|
+
- `with(condition)` will set a customizable argument to either `true` or `false`, based
|
|
6
6
|
on current arguments,
|
|
7
|
-
- `
|
|
8
|
-
renders it when
|
|
9
|
-
- `
|
|
10
|
-
renders it
|
|
7
|
+
- `with(conditionalFallback)` takes a `FunctionComponent` as parameter, and
|
|
8
|
+
renders it when a customizable argument is set to `true`, filling the `render` argument in the process,
|
|
9
|
+
- `with(conditionalRender)` also takes a `FunctionComponent` as parameter, and
|
|
10
|
+
renders it if the `render` argument was not filled earlier.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
to chain multiple conditions with a different fallback for each. Subsequent calls
|
|
14
|
-
to `withCondition` will take into account preceding conditions, so that `withConditionalRender`
|
|
15
|
-
is only called when all conditions return `true`.
|
|
12
|
+
## Usage
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
```tsx
|
|
15
|
+
import { ModularComponent } from '@modular-component/core'
|
|
16
|
+
import { condition, conditionalFallback, conditionalRender } from '@modular-component/with-conditional-render'
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const ConditionalComponent = ModularComponent<{ enabled?: boolean }>()
|
|
19
|
+
.with(condition('disabled', ({ props }) => props.enabled !== true))
|
|
20
|
+
.with(conditionalFallback('disabled', () => <>I'm disabled!</>))
|
|
21
|
+
.with(lifecycle(() => {
|
|
22
|
+
// Some data fetching logic...
|
|
23
|
+
return { loading, data }
|
|
24
|
+
}))
|
|
25
|
+
.with(condition('loading', ({ lifecycle }) => lifecycle.loading === false))
|
|
26
|
+
.with(conditionalFallback('loading', () => <>I'm loading!</>))
|
|
27
|
+
.with(conditionalRender(({ lifecycle }) => (
|
|
28
|
+
<>I'm enabled and loaded, here is the content: {lifecycle.data}</>
|
|
29
|
+
)))
|
|
21
30
|
```
|
|
22
31
|
|
|
32
|
+
## Multiple conditions and fallbacks
|
|
33
|
+
|
|
34
|
+
You can use the `condition` and `conditionalFallback` multiple times in the same pipeline by providing different
|
|
35
|
+
argument names as the first parameter.
|
|
36
|
+
|
|
37
|
+
## Implementation
|
|
38
|
+
|
|
39
|
+
The implementation for those stages is a bit more involved than other official extensions. Here, we have restrictions
|
|
40
|
+
for each stage, as well as stage hooks.
|
|
41
|
+
|
|
23
42
|
```tsx
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
const ModularComponent = modularFactory.extend(WithConditionalRender).build()
|
|
28
|
-
|
|
29
|
-
const MyModularComponent = ModularComponent<{
|
|
30
|
-
isAuthenticated: boolean
|
|
31
|
-
isOwner: boolean
|
|
32
|
-
}>()
|
|
33
|
-
.withCondition(({ props }) => props.isAuthenticated)
|
|
34
|
-
.withConditionalFallback(() => (
|
|
35
|
-
<div>You need to be authenticated to see this page</div>
|
|
36
|
-
))
|
|
37
|
-
.withCondition(({ props }) => props.isOwner)
|
|
38
|
-
.withConditionalFallback(() => (
|
|
39
|
-
<div>You don't have enough permissions to see this page</div>
|
|
40
|
-
))
|
|
41
|
-
.withConditionalRender(({ components }) => (
|
|
42
|
-
<>
|
|
43
|
-
<h1>Hello, Owner</h1>
|
|
44
|
-
</>
|
|
45
|
-
))
|
|
46
|
-
```
|
|
43
|
+
import React, { FunctionComponent } from 'react'
|
|
44
|
+
import { ModularStage } from '@modular-component/core'
|
|
47
45
|
|
|
48
|
-
|
|
46
|
+
export function condition<Args, Name extends string>(
|
|
47
|
+
name: Name,
|
|
48
|
+
useCondition: (args: Args) => boolean,
|
|
49
|
+
): ModularStage<Name, (args: Args) => boolean> {
|
|
50
|
+
return { field: name, useStage: useCondition }
|
|
51
|
+
}
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
export function conditionalFallback<
|
|
54
|
+
Args extends { [key in Name]: boolean } & {
|
|
55
|
+
render?: ReturnType<FunctionComponent>
|
|
56
|
+
},
|
|
57
|
+
Name extends string,
|
|
58
|
+
>(
|
|
59
|
+
name: Name,
|
|
60
|
+
useRender: (args: Args) => ReturnType<FunctionComponent>,
|
|
61
|
+
): ModularStage<`render-${Name}`, (args: Args) => void> {
|
|
62
|
+
return {
|
|
63
|
+
field: `render-${name}`,
|
|
64
|
+
useStage: (args: Args) => {
|
|
65
|
+
args.render = !args[name] || args.render ? args.render : useRender(args)
|
|
66
|
+
},
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function conditionalRender<Args, Ref>(
|
|
71
|
+
useRender: (
|
|
72
|
+
args: Args,
|
|
73
|
+
ref: React.ForwardedRef<Ref>,
|
|
74
|
+
) => ReturnType<FunctionComponent>,
|
|
75
|
+
): ModularStage<
|
|
76
|
+
'render',
|
|
77
|
+
(args: Args, ref: React.ForwardedRef<Ref>) => ReturnType<FunctionComponent>
|
|
78
|
+
> {
|
|
79
|
+
return {
|
|
80
|
+
field: 'render',
|
|
81
|
+
useStage: (args: Args, ref: React.ForwardedRef<Ref>) =>
|
|
82
|
+
(args as any).render ?? useRender(args, ref),
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,47 +1,10 @@
|
|
|
1
|
-
import { FunctionComponent } from 'react';
|
|
2
|
-
|
|
3
|
-
declare
|
|
4
|
-
declare
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
[withConditionalFallback]: {
|
|
12
|
-
restrict: FunctionComponent<Args>;
|
|
13
|
-
transform: ReturnType<FunctionComponent<Args>> | null;
|
|
14
|
-
};
|
|
15
|
-
[withConditionalRender]: {
|
|
16
|
-
restrict: FunctionComponent<Args>;
|
|
17
|
-
transform: ReturnType<FunctionComponent<Args>> | null;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
export declare const WithConditionalRender: {
|
|
22
|
-
readonly Condition: {
|
|
23
|
-
readonly symbol: typeof withCondition;
|
|
24
|
-
readonly field: "condition";
|
|
25
|
-
readonly transform: <A extends {
|
|
26
|
-
condition?: boolean | undefined;
|
|
27
|
-
}, C extends (args: A) => boolean>(args: A, useCondition: C) => boolean;
|
|
28
|
-
};
|
|
29
|
-
readonly ConditionalRender: {
|
|
30
|
-
readonly symbol: typeof withConditionalRender;
|
|
31
|
-
readonly field: "render";
|
|
32
|
-
readonly transform: <A_1 extends {
|
|
33
|
-
condition?: boolean | undefined;
|
|
34
|
-
render?: import("react").ReactElement<any, any> | null | undefined;
|
|
35
|
-
}, P extends FunctionComponent<A_1>>(args: A_1, useRender: P) => import("react").ReactElement<any, any> | null | undefined;
|
|
36
|
-
};
|
|
37
|
-
readonly ConditionalFallback: {
|
|
38
|
-
readonly symbol: typeof withConditionalFallback;
|
|
39
|
-
readonly field: "render";
|
|
40
|
-
readonly transform: <A_2 extends {
|
|
41
|
-
condition?: boolean | undefined;
|
|
42
|
-
render?: import("react").ReactElement<any, any> | null | undefined;
|
|
43
|
-
}, P_1 extends FunctionComponent<A_2>>(args: A_2, useRender: P_1) => import("react").ReactElement<any, any> | null | undefined;
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
export {};
|
|
1
|
+
import React, { FunctionComponent } from 'react';
|
|
2
|
+
import { ModularStage } from '@modular-component/core';
|
|
3
|
+
export declare function condition<Args, Name extends string>(name: Name, useCondition: (args: Args) => boolean): ModularStage<Name, (args: Args) => boolean>;
|
|
4
|
+
export declare function conditionalFallback<Args extends {
|
|
5
|
+
[key in Name]: boolean;
|
|
6
|
+
} & {
|
|
7
|
+
render?: ReturnType<FunctionComponent>;
|
|
8
|
+
}, Name extends string>(name: Name, useRender: (args: Args) => ReturnType<FunctionComponent>): ModularStage<`render-${Name}`, (args: Args) => void>;
|
|
9
|
+
export declare function conditionalRender<Args, Ref>(useRender: (args: Args, ref: React.ForwardedRef<Ref>) => ReturnType<FunctionComponent>): ModularStage<'render', (args: Args, ref: React.ForwardedRef<Ref>) => ReturnType<FunctionComponent>>;
|
|
47
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAEtD,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,SAAS,MAAM,EACjD,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,GACpC,YAAY,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAE7C;AAED,wBAAgB,mBAAmB,CACjC,IAAI,SAAS;KAAG,GAAG,IAAI,IAAI,GAAG,OAAO;CAAE,GAAG;IACxC,MAAM,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAA;CACvC,EACD,IAAI,SAAS,MAAM,EAEnB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,UAAU,CAAC,iBAAiB,CAAC,GACvD,YAAY,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,CAOtD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,GAAG,EACzC,SAAS,EAAE,CACT,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,KACzB,UAAU,CAAC,iBAAiB,CAAC,GACjC,YAAY,CACb,QAAQ,EACR,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,UAAU,CAAC,iBAAiB,CAAC,CAC5E,CAMA"}
|
package/dist/index.js
CHANGED
|
@@ -1,32 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
transform: (args, useCondition) => args.condition !== false && useCondition(args),
|
|
10
|
-
},
|
|
11
|
-
ConditionalRender: {
|
|
12
|
-
symbol: withConditionalRender,
|
|
13
|
-
field: 'render',
|
|
14
|
-
transform: (args, useRender) => {
|
|
15
|
-
if (args.condition === false) {
|
|
16
|
-
return args.render;
|
|
17
|
-
}
|
|
18
|
-
return useRender(args);
|
|
1
|
+
export function condition(name, useCondition) {
|
|
2
|
+
return { field: name, useStage: useCondition };
|
|
3
|
+
}
|
|
4
|
+
export function conditionalFallback(name, useRender) {
|
|
5
|
+
return {
|
|
6
|
+
field: `render-${name}`,
|
|
7
|
+
useStage: (args) => {
|
|
8
|
+
args.render = !args[name] || args.render ? args.render : useRender(args);
|
|
19
9
|
},
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function conditionalRender(useRender) {
|
|
13
|
+
return {
|
|
23
14
|
field: 'render',
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
return useRender(args);
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
});
|
|
15
|
+
useStage: (args, ref) => args.render ?? useRender(args, ref),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
32
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,SAAS,CACvB,IAAU,EACV,YAAqC;IAErC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAMjC,IAAU,EACV,SAAwD;IAExD,OAAO;QACL,KAAK,EAAE,UAAU,IAAI,EAAE;QACvB,QAAQ,EAAE,CAAC,IAAU,EAAE,EAAE;YACvB,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAC1E,CAAC;KACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,SAGkC;IAKlC,OAAO;QACL,KAAK,EAAE,QAAQ;QACf,QAAQ,EAAE,CAAC,IAAU,EAAE,GAA4B,EAAE,EAAE,CACpD,IAAY,CAAC,MAAM,IAAI,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC;KAC/C,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"Default",
|
|
9
9
|
"Conditional"
|
|
10
10
|
],
|
|
11
|
-
"version": "0.1
|
|
11
|
+
"version": "0.2.1",
|
|
12
12
|
"type": "module",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"publishConfig": {
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
"license": "cp ../../LICENSE ./LICENSE"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@modular-component/core": "0.1
|
|
29
|
+
"@modular-component/core": "0.2.1"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"react": ">=17 <19"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/react": "^18.0.17",
|
|
36
|
-
"typescript": "^
|
|
36
|
+
"typescript": "^5.2.2"
|
|
37
37
|
},
|
|
38
38
|
"main": "dist/index.js",
|
|
39
39
|
"types": "dist/index.d.ts"
|
package/src/index.ts
CHANGED
|
@@ -1,74 +1,42 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import React, { FunctionComponent } from 'react'
|
|
2
|
+
import { ModularStage } from '@modular-component/core'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
declare module '@modular-component/core' {
|
|
10
|
-
export interface ModularStages<Args, Value> {
|
|
11
|
-
[withCondition]: {
|
|
12
|
-
restrict: (args: Args) => boolean
|
|
13
|
-
transform: ReturnType<
|
|
14
|
-
Value extends (args: Args) => boolean ? Value : never
|
|
15
|
-
>
|
|
16
|
-
}
|
|
17
|
-
[withConditionalFallback]: {
|
|
18
|
-
restrict: FunctionComponent<Args>
|
|
19
|
-
transform: ReturnType<FunctionComponent<Args>> | null
|
|
20
|
-
}
|
|
21
|
-
[withConditionalRender]: {
|
|
22
|
-
restrict: FunctionComponent<Args>
|
|
23
|
-
transform: ReturnType<FunctionComponent<Args>> | null
|
|
24
|
-
}
|
|
25
|
-
}
|
|
4
|
+
export function condition<Args, Name extends string>(
|
|
5
|
+
name: Name,
|
|
6
|
+
useCondition: (args: Args) => boolean,
|
|
7
|
+
): ModularStage<Name, (args: Args) => boolean> {
|
|
8
|
+
return { field: name, useStage: useCondition }
|
|
26
9
|
}
|
|
27
10
|
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
field: 'condition',
|
|
32
|
-
transform: <
|
|
33
|
-
A extends { condition?: boolean },
|
|
34
|
-
C extends (args: A) => boolean,
|
|
35
|
-
>(
|
|
36
|
-
args: A,
|
|
37
|
-
useCondition: C,
|
|
38
|
-
) => args.condition !== false && useCondition(args),
|
|
11
|
+
export function conditionalFallback<
|
|
12
|
+
Args extends { [key in Name]: boolean } & {
|
|
13
|
+
render?: ReturnType<FunctionComponent>
|
|
39
14
|
},
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
) => {
|
|
50
|
-
if (args.condition === false) {
|
|
51
|
-
return args.render
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return useRender(args)
|
|
15
|
+
Name extends string,
|
|
16
|
+
>(
|
|
17
|
+
name: Name,
|
|
18
|
+
useRender: (args: Args) => ReturnType<FunctionComponent>,
|
|
19
|
+
): ModularStage<`render-${Name}`, (args: Args) => void> {
|
|
20
|
+
return {
|
|
21
|
+
field: `render-${name}`,
|
|
22
|
+
useStage: (args: Args) => {
|
|
23
|
+
args.render = !args[name] || args.render ? args.render : useRender(args)
|
|
55
24
|
},
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
symbol: withConditionalFallback,
|
|
59
|
-
field: 'render',
|
|
60
|
-
transform: <
|
|
61
|
-
A extends { condition?: boolean; render?: ReturnType<FunctionComponent> },
|
|
62
|
-
P extends FunctionComponent<A>,
|
|
63
|
-
>(
|
|
64
|
-
args: A,
|
|
65
|
-
useRender: P,
|
|
66
|
-
) => {
|
|
67
|
-
if (args.condition !== false || args.render) {
|
|
68
|
-
return args.render
|
|
69
|
-
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
70
27
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
28
|
+
export function conditionalRender<Args, Ref>(
|
|
29
|
+
useRender: (
|
|
30
|
+
args: Args,
|
|
31
|
+
ref: React.ForwardedRef<Ref>,
|
|
32
|
+
) => ReturnType<FunctionComponent>,
|
|
33
|
+
): ModularStage<
|
|
34
|
+
'render',
|
|
35
|
+
(args: Args, ref: React.ForwardedRef<Ref>) => ReturnType<FunctionComponent>
|
|
36
|
+
> {
|
|
37
|
+
return {
|
|
38
|
+
field: 'render',
|
|
39
|
+
useStage: (args: Args, ref: React.ForwardedRef<Ref>) =>
|
|
40
|
+
(args as any).render ?? useRender(args, ref),
|
|
41
|
+
}
|
|
42
|
+
}
|