@webiny/react-composition 0.0.0-unstable.78f581c1d2 → 0.0.0-unstable.7be00a75a9

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.js","sources":["../src/decorators.tsx"],"sourcesContent":["import React from \"react\";\nimport { Compose } from \"~/Compose.js\";\nimport type { GetDecoratee, GetDecorateeParams } from \"~/createDecorator.js\";\nimport type {\n DecoratableComponent,\n GenericComponent,\n Decorator,\n GenericHook,\n DecoratableHook,\n ComponentDecorator\n} from \"~/types.js\";\n\nexport interface ShouldDecorate<TDecorator = any, TComponent = any> {\n (decoratorProps: TDecorator, componentProps: TComponent): boolean;\n}\n\nexport function createConditionalDecorator<TDecoratee extends GenericComponent>(\n shouldDecorate: ShouldDecorate,\n decorator: Decorator<TDecoratee>,\n decoratorProps: unknown\n): Decorator<TDecoratee> {\n return (Original => {\n const DecoratedComponent = React.memo(decorator(Original));\n DecoratedComponent.displayName = Original.displayName;\n\n return function ShouldDecorate(props: unknown) {\n if (shouldDecorate(decoratorProps, props)) {\n // @ts-expect-error\n return <DecoratedComponent {...props} />;\n }\n\n // @ts-expect-error\n return <Original {...props} />;\n };\n }) as Decorator<TDecoratee>;\n}\n\nconst memoizedComponent = <T extends GenericComponent>(decorator: Decorator<T>) => {\n return (decoratee: T) => {\n return React.memo(decorator(decoratee));\n };\n};\n\nexport function createDecoratorFactory<TDecorator>() {\n return function from<TDecoratable extends DecoratableComponent>(\n decoratable: TDecoratable,\n shouldDecorate?: ShouldDecorate<TDecorator, GetDecorateeParams<GetDecoratee<TDecoratable>>>\n ) {\n return function createDecorator(decorator: ComponentDecorator<GetDecoratee<TDecoratable>>) {\n return function DecoratorPlugin(props: TDecorator) {\n if (shouldDecorate) {\n const componentDecorator = createConditionalDecorator<GenericComponent>(\n shouldDecorate,\n decorator as unknown as Decorator<GenericComponent>,\n props\n );\n\n return <Compose function={decoratable} with={componentDecorator} />;\n }\n\n return (\n <Compose\n function={decoratable}\n with={memoizedComponent(\n decorator as unknown as Decorator<GenericComponent>\n )}\n />\n );\n };\n };\n };\n}\n\nexport function createHookDecoratorFactory() {\n return function from<TDecoratable extends DecoratableHook>(decoratable: TDecoratable) {\n return function createDecorator(decorator: Decorator<GetDecoratee<TDecoratable>>) {\n return function DecoratorPlugin() {\n return (\n <Compose\n function={decoratable}\n with={decorator as unknown as Decorator<GenericHook>}\n />\n );\n };\n };\n };\n}\n\nexport function withDecoratorFactory<TDecorator>() {\n return function WithDecorator<TDecoratable extends DecoratableComponent>(\n Component: TDecoratable,\n shouldDecorate?: ShouldDecorate<TDecorator, GetDecorateeParams<GetDecoratee<TDecoratable>>>\n ) {\n const createDecorator = createDecoratorFactory<TDecorator>()(Component, shouldDecorate);\n\n return Object.assign(Component, { createDecorator }) as TDecoratable & {\n createDecorator: typeof createDecorator;\n };\n };\n}\n\nexport function withHookDecoratorFactory() {\n return function WithHookDecorator<TDecoratable extends DecoratableHook>(hook: TDecoratable) {\n const createDecorator = createHookDecoratorFactory()(hook);\n\n return Object.assign(hook, { createDecorator }) as unknown as DecoratableHook<\n GenericHook<\n GetDecorateeParams<GetDecoratee<TDecoratable>>,\n ReturnType<GetDecoratee<TDecoratable>>\n >\n > & { createDecorator: typeof createDecorator };\n };\n}\n"],"names":["createConditionalDecorator","shouldDecorate","decorator","decoratorProps","Original","DecoratedComponent","React","props","memoizedComponent","decoratee","createDecoratorFactory","decoratable","componentDecorator","Compose","createHookDecoratorFactory","withDecoratorFactory","Component","createDecorator","Object","withHookDecoratorFactory","hook"],"mappings":";;AAgBO,SAASA,2BACZC,cAA8B,EAC9BC,SAAgC,EAChCC,cAAuB;IAEvB,OAAQC,CAAAA;QACJ,MAAMC,qBAAqB,WAArBA,GAAqBC,MAAAA,IAAU,CAACJ,UAAUE;QAChDC,mBAAmB,WAAW,GAAGD,SAAS,WAAW;QAErD,OAAO,SAAwBG,KAAc;YACzC,IAAIN,eAAeE,gBAAgBI,QAE/B,OAAO,WAAP,GAAO,oBAACF,oBAAuBE;YAInC,OAAO,WAAP,GAAO,oBAACH,UAAaG;QACzB;IACJ;AACJ;AAEA,MAAMC,oBAAoB,CAA6BN,YAC5C,CAACO,YACG,WAAP,GAAOH,MAAAA,IAAU,CAACJ,UAAUO;AAI7B,SAASC;IACZ,OAAO,SACHC,WAAyB,EACzBV,cAA2F;QAE3F,OAAO,SAAyBC,SAAyD;YACrF,OAAO,SAAyBK,KAAiB;gBAC7C,IAAIN,gBAAgB;oBAChB,MAAMW,qBAAqBZ,2BACvBC,gBACAC,WACAK;oBAGJ,OAAO,WAAP,GAAO,oBAACM,SAAOA;wBAAC,UAAUF;wBAAa,MAAMC;;gBACjD;gBAEA,OAAO,WAAP,GACI,oBAACC,SAAOA;oBACJ,UAAUF;oBACV,MAAMH,kBACFN;;YAIhB;QACJ;IACJ;AACJ;AAEO,SAASY;IACZ,OAAO,SAAoDH,WAAyB;QAChF,OAAO,SAAyBT,SAAgD;YAC5E,OAAO;gBACH,OAAO,WAAP,GACI,oBAACW,SAAOA;oBACJ,UAAUF;oBACV,MAAMT;;YAGlB;QACJ;IACJ;AACJ;AAEO,SAASa;IACZ,OAAO,SACHC,SAAuB,EACvBf,cAA2F;QAE3F,MAAMgB,kBAAkBP,yBAAqCM,WAAWf;QAExE,OAAOiB,OAAO,MAAM,CAACF,WAAW;YAAEC;QAAgB;IAGtD;AACJ;AAEO,SAASE;IACZ,OAAO,SAAiEC,IAAkB;QACtF,MAAMH,kBAAkBH,6BAA6BM;QAErD,OAAOF,OAAO,MAAM,CAACE,MAAM;YAAEH;QAAgB;IAMjD;AACJ"}
@@ -0,0 +1,21 @@
1
+ import type { ComponentType } from "react";
2
+ import type { Decorator, GenericComponent, GenericHook } from "../types.js";
3
+ type Listener = () => void;
4
+ export declare class CompositionStore {
5
+ private scopes;
6
+ private version;
7
+ private listeners;
8
+ register(component: ComponentType<unknown>, hocs: Decorator<GenericComponent | GenericHook>[], scope?: string, inherit?: boolean, silent?: boolean, replaces?: Decorator<GenericComponent | GenericHook>[]): () => void;
9
+ unregister(component: ComponentType<unknown>, hocs: Decorator<GenericComponent | GenericHook>[], scope?: string): void;
10
+ getComponent(component: ComponentType<unknown>, scope?: string[]): GenericComponent | GenericHook | undefined;
11
+ /**
12
+ * Bump version and notify listeners without changing store state.
13
+ * Used after a render-phase atomic swap (silent) to inform subscribers
14
+ * that the swap has settled and they should re-render with the final state.
15
+ */
16
+ notify(): void;
17
+ subscribe: (listener: Listener) => (() => void);
18
+ getSnapshot: () => number;
19
+ private notifyListeners;
20
+ }
21
+ export {};
@@ -0,0 +1,89 @@
1
+ import { compose } from "../Context.js";
2
+ class CompositionStore {
3
+ register(component, hocs, scope = "*", inherit = false, silent = false, replaces = []) {
4
+ const scopeMap = this.scopes.get(scope) || new Map();
5
+ const recipe = scopeMap.get(component) || {
6
+ component: component,
7
+ hocs: []
8
+ };
9
+ const newHocs = hocs.filter((hoc)=>!recipe.hocs.includes(hoc));
10
+ if (0 === newHocs.length && 0 === replaces.length) return ()=>this.unregister(component, hocs, scope);
11
+ const existingHocs = replaces.length ? recipe.hocs.filter((hoc)=>!replaces.includes(hoc)) : [
12
+ ...recipe.hocs
13
+ ];
14
+ if (inherit && "*" !== scope) {
15
+ const globalScope = this.scopes.get("*") || new Map();
16
+ const globalRecipe = globalScope.get(component) || {
17
+ component: component,
18
+ hocs: []
19
+ };
20
+ const globalHocsToAdd = globalRecipe.hocs.filter((hoc)=>!existingHocs.includes(hoc));
21
+ existingHocs.unshift(...globalHocsToAdd);
22
+ }
23
+ const finalHocs = [
24
+ ...existingHocs,
25
+ ...newHocs
26
+ ];
27
+ scopeMap.set(component, {
28
+ component: compose(...[
29
+ ...finalHocs
30
+ ].reverse())(component),
31
+ hocs: finalHocs
32
+ });
33
+ this.scopes.set(scope, scopeMap);
34
+ this.version++;
35
+ if (!silent) this.notifyListeners();
36
+ return ()=>this.unregister(component, hocs, scope);
37
+ }
38
+ unregister(component, hocs, scope = "*") {
39
+ const scopeMap = this.scopes.get(scope);
40
+ if (!scopeMap) return;
41
+ const recipe = scopeMap.get(component);
42
+ if (!recipe) return;
43
+ const newHocs = recipe.hocs.filter((hoc)=>!hocs.includes(hoc));
44
+ if (newHocs.length === recipe.hocs.length) return;
45
+ if (0 === newHocs.length) scopeMap.delete(component);
46
+ else scopeMap.set(component, {
47
+ component: compose(...[
48
+ ...newHocs
49
+ ].reverse())(component),
50
+ hocs: newHocs
51
+ });
52
+ this.version++;
53
+ this.notifyListeners();
54
+ }
55
+ getComponent(component, scope = []) {
56
+ const scopesToResolve = [
57
+ "*",
58
+ ...scope
59
+ ].reverse();
60
+ for (const s of scopesToResolve){
61
+ const scopeMap = this.scopes.get(s);
62
+ if (!scopeMap) continue;
63
+ const composed = scopeMap.get(component);
64
+ if (composed) return composed.component;
65
+ }
66
+ }
67
+ notify() {
68
+ this.version++;
69
+ this.notifyListeners();
70
+ }
71
+ notifyListeners() {
72
+ for (const listener of this.listeners)listener();
73
+ }
74
+ constructor(){
75
+ this.scopes = new Map();
76
+ this.version = 0;
77
+ this.listeners = new Set();
78
+ this.subscribe = (listener)=>{
79
+ this.listeners.add(listener);
80
+ return ()=>{
81
+ this.listeners.delete(listener);
82
+ };
83
+ };
84
+ this.getSnapshot = ()=>this.version;
85
+ }
86
+ }
87
+ export { CompositionStore };
88
+
89
+ //# sourceMappingURL=CompositionStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain/CompositionStore.js","sources":["../../src/domain/CompositionStore.ts"],"sourcesContent":["import type { ComponentType } from \"react\";\nimport { compose } from \"~/Context.js\";\nimport type { Decorator, GenericComponent, GenericHook } from \"~/types.js\";\n\ninterface ComposedComponent {\n component: GenericHook | GenericComponent;\n hocs: Decorator<GenericComponent | GenericHook>[];\n}\n\ntype ComposedComponents = Map<ComponentType<unknown>, ComposedComponent>;\ntype ComponentScopes = Map<string, ComposedComponents>;\n\ntype Listener = () => void;\n\nexport class CompositionStore {\n private scopes: ComponentScopes = new Map();\n private version = 0;\n private listeners = new Set<Listener>();\n\n register(\n component: ComponentType<unknown>,\n hocs: Decorator<GenericComponent | GenericHook>[],\n scope = \"*\",\n inherit = false,\n silent = false,\n replaces: Decorator<GenericComponent | GenericHook>[] = []\n ): () => void {\n const scopeMap: ComposedComponents = this.scopes.get(scope) || new Map();\n const recipe = scopeMap.get(component) || {\n component: component as any,\n hocs: [] as Decorator<GenericComponent | GenericHook>[]\n };\n\n // Idempotent: skip if all HOCs are already registered (handles StrictMode double-render).\n const newHocs = hocs.filter(hoc => !recipe.hocs.includes(hoc));\n if (newHocs.length === 0 && replaces.length === 0) {\n return () => this.unregister(component, hocs, scope);\n }\n\n // Atomically remove the HOCs being replaced so the store never transiently\n // holds both the old and new decorators at the same time. This prevents\n // useSyncExternalStore subscribers from seeing a doubly-wrapped component\n // in the window between a render-phase registration and its effect cleanup.\n const existingHocs = replaces.length\n ? recipe.hocs.filter(hoc => !replaces.includes(hoc))\n : [...recipe.hocs];\n if (inherit && scope !== \"*\") {\n const globalScope = this.scopes.get(\"*\") || new Map();\n const globalRecipe = globalScope.get(component) || {\n component: component as any,\n hocs: [] as Decorator<GenericComponent | GenericHook>[]\n };\n // Only prepend global HOCs that aren't already present.\n const globalHocsToAdd = globalRecipe.hocs.filter(\n (hoc: Decorator<GenericComponent | GenericHook>) => !existingHocs.includes(hoc)\n );\n existingHocs.unshift(...globalHocsToAdd);\n }\n\n const finalHocs = [...existingHocs, ...newHocs];\n\n scopeMap.set(component, {\n component: compose(...[...finalHocs].reverse())(component as any),\n hocs: finalHocs\n });\n\n this.scopes.set(scope, scopeMap);\n\n // Bump the version so useSyncExternalStore sees a new snapshot.\n this.version++;\n\n // When called during render (silent=true), don't notify listeners —\n // that would trigger setState in other components mid-render.\n // Components that render after this point will see the updated snapshot.\n if (!silent) {\n this.notifyListeners();\n }\n\n return () => this.unregister(component, hocs, scope);\n }\n\n unregister(\n component: ComponentType<unknown>,\n hocs: Decorator<GenericComponent | GenericHook>[],\n scope = \"*\"\n ): void {\n const scopeMap = this.scopes.get(scope);\n if (!scopeMap) {\n return;\n }\n\n const recipe = scopeMap.get(component);\n if (!recipe) {\n return;\n }\n\n const newHocs = recipe.hocs.filter(hoc => !hocs.includes(hoc));\n if (newHocs.length === recipe.hocs.length) {\n // Nothing was removed.\n return;\n }\n\n if (newHocs.length === 0) {\n scopeMap.delete(component);\n } else {\n scopeMap.set(component, {\n component: compose(...[...newHocs].reverse())(component as any),\n hocs: newHocs\n });\n }\n\n this.version++;\n this.notifyListeners();\n }\n\n getComponent(\n component: ComponentType<unknown>,\n scope: string[] = []\n ): GenericComponent | GenericHook | undefined {\n const scopesToResolve = [\"*\", ...scope].reverse();\n for (const s of scopesToResolve) {\n const scopeMap = this.scopes.get(s);\n if (!scopeMap) {\n continue;\n }\n const composed = scopeMap.get(component);\n if (composed) {\n return composed.component;\n }\n }\n return undefined;\n }\n\n /**\n * Bump version and notify listeners without changing store state.\n * Used after a render-phase atomic swap (silent) to inform subscribers\n * that the swap has settled and they should re-render with the final state.\n */\n notify(): void {\n this.version++;\n this.notifyListeners();\n }\n\n subscribe = (listener: Listener): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = (): number => {\n return this.version;\n };\n\n private notifyListeners(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n"],"names":["CompositionStore","component","hocs","scope","inherit","silent","replaces","scopeMap","Map","recipe","newHocs","hoc","existingHocs","globalScope","globalRecipe","globalHocsToAdd","finalHocs","compose","scopesToResolve","s","composed","listener","Set"],"mappings":"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"}
package/index.d.ts CHANGED
@@ -1,4 +1,9 @@
1
- export * from "./Context";
2
- export * from "./Compose";
3
- export * from "./makeComposable";
4
- export * from "./createComponentPlugin";
1
+ export * from "./Context.js";
2
+ export * from "./Compose.js";
3
+ export * from "./makeComposable.js";
4
+ export * from "./makeDecoratable.js";
5
+ export * from "./createDecorator.js";
6
+ export * from "./decorators.js";
7
+ export * from "./CompositionScope.js";
8
+ export { CompositionStore } from "./domain/CompositionStore.js";
9
+ export type * from "./types.js";
package/index.js CHANGED
@@ -1,57 +1,8 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
-
7
- var _Context = require("./Context");
8
-
9
- Object.keys(_Context).forEach(function (key) {
10
- if (key === "default" || key === "__esModule") return;
11
- if (key in exports && exports[key] === _Context[key]) return;
12
- Object.defineProperty(exports, key, {
13
- enumerable: true,
14
- get: function get() {
15
- return _Context[key];
16
- }
17
- });
18
- });
19
-
20
- var _Compose = require("./Compose");
21
-
22
- Object.keys(_Compose).forEach(function (key) {
23
- if (key === "default" || key === "__esModule") return;
24
- if (key in exports && exports[key] === _Compose[key]) return;
25
- Object.defineProperty(exports, key, {
26
- enumerable: true,
27
- get: function get() {
28
- return _Compose[key];
29
- }
30
- });
31
- });
32
-
33
- var _makeComposable = require("./makeComposable");
34
-
35
- Object.keys(_makeComposable).forEach(function (key) {
36
- if (key === "default" || key === "__esModule") return;
37
- if (key in exports && exports[key] === _makeComposable[key]) return;
38
- Object.defineProperty(exports, key, {
39
- enumerable: true,
40
- get: function get() {
41
- return _makeComposable[key];
42
- }
43
- });
44
- });
45
-
46
- var _createComponentPlugin = require("./createComponentPlugin");
47
-
48
- Object.keys(_createComponentPlugin).forEach(function (key) {
49
- if (key === "default" || key === "__esModule") return;
50
- if (key in exports && exports[key] === _createComponentPlugin[key]) return;
51
- Object.defineProperty(exports, key, {
52
- enumerable: true,
53
- get: function get() {
54
- return _createComponentPlugin[key];
55
- }
56
- });
57
- });
1
+ export * from "./Context.js";
2
+ export * from "./Compose.js";
3
+ export * from "./makeComposable.js";
4
+ export * from "./makeDecoratable.js";
5
+ export * from "./createDecorator.js";
6
+ export * from "./decorators.js";
7
+ export * from "./CompositionScope.js";
8
+ export { CompositionStore } from "./domain/CompositionStore.js";
@@ -1,3 +1,43 @@
1
- import React from "react";
2
- import { ComposableFC } from "./Compose";
3
- export declare function makeComposable<TProps>(name: string, Component?: React.FC<TProps>): ComposableFC<TProps>;
1
+ import type { GenericComponent } from "./types.js";
2
+ /**
3
+ * @deprecated Use `makeDecoratable` instead.
4
+ */
5
+ export declare function makeComposable<T extends GenericComponent>(name: string, Component?: T): (((() => null) | T) & {
6
+ original: (() => null) | T;
7
+ originalName: string;
8
+ displayName: string;
9
+ }) & {
10
+ original: ((() => null) | T) & {
11
+ original: (() => null) | T;
12
+ originalName: string;
13
+ displayName: string;
14
+ };
15
+ originalName: string;
16
+ displayName: string;
17
+ } & {
18
+ createDecorator: (decorator: import("~/types.js").ComponentDecorator<import("./createDecorator").GetDecoratee<(() => null) & {
19
+ original: (() => null) | T;
20
+ originalName: string;
21
+ displayName: string;
22
+ } & {
23
+ original: ((() => null) | T) & {
24
+ original: (() => null) | T;
25
+ originalName: string;
26
+ displayName: string;
27
+ };
28
+ originalName: string;
29
+ displayName: string;
30
+ }> | import("./createDecorator").GetDecoratee<T & {
31
+ original: (() => null) | T;
32
+ originalName: string;
33
+ displayName: string;
34
+ } & {
35
+ original: ((() => null) | T) & {
36
+ original: (() => null) | T;
37
+ originalName: string;
38
+ displayName: string;
39
+ };
40
+ originalName: string;
41
+ displayName: string;
42
+ }>>) => (props: unknown) => import("react").JSX.Element;
43
+ };
package/makeComposable.js CHANGED
@@ -1,72 +1,11 @@
1
- "use strict";
2
-
3
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
-
5
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
6
-
7
- Object.defineProperty(exports, "__esModule", {
8
- value: true
9
- });
10
- exports.makeComposable = makeComposable;
11
-
12
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
13
-
14
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
15
-
16
- var _react = _interopRequireWildcard(require("react"));
17
-
18
- var _lodash = _interopRequireDefault(require("lodash.debounce"));
19
-
20
- var _Context = require("./Context");
21
-
22
- var ComposableContext = /*#__PURE__*/(0, _react.createContext)([]);
1
+ import { createContext } from "react";
2
+ import { makeDecoratable } from "./makeDecoratable.js";
3
+ const ComposableContext = /*#__PURE__*/ createContext([]);
23
4
  ComposableContext.displayName = "ComposableContext";
24
-
25
- function useComposableParents() {
26
- var context = (0, _react.useContext)(ComposableContext);
27
-
28
- if (!context) {
29
- return [];
30
- }
31
-
32
- return context;
33
- }
34
-
35
- var createEmptyRenderer = function createEmptyRenderer(name) {
36
- return (0, _defineProperty2.default)({}, name, function () {
37
- (0, _react.useEffect)(function () {
38
- // We need to debounce the log, as it sometimes only requires a single tick to get the new
39
- // composed component to render, and we don't want to scare developers for no reason.
40
- var debounced = (0, _lodash.default)(function () {
41
- console.info("<".concat(name, "/> is not implemented! To provide an implementation, use the <Compose/> component."));
42
- }, 100);
43
- return function () {
44
- debounced.cancel();
45
- };
46
- }, []);
47
- return null;
48
- })[name];
49
- };
50
-
5
+ const nullRenderer = ()=>null;
51
6
  function makeComposable(name, Component) {
52
- if (!Component) {
53
- Component = createEmptyRenderer(name);
54
- }
55
-
56
- var Composable = function Composable(props) {
57
- var parents = useComposableParents();
58
- var ComposedComponent = (0, _Context.useComponent)(Component);
59
- var context = (0, _react.useMemo)(function () {
60
- return [].concat((0, _toConsumableArray2.default)(parents), [name]);
61
- }, [parents, name]);
62
- return /*#__PURE__*/_react.default.createElement(ComposableContext.Provider, {
63
- value: context
64
- }, /*#__PURE__*/_react.default.createElement(ComposedComponent, props, props.children));
65
- };
7
+ return makeDecoratable(name, Component ?? nullRenderer);
8
+ }
9
+ export { makeComposable };
66
10
 
67
- Component.displayName = name;
68
- Composable.original = Component;
69
- Composable.originalName = name;
70
- Composable.displayName = "Composable<".concat(name, ">");
71
- return Composable;
72
- }
11
+ //# sourceMappingURL=makeComposable.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["ComposableContext","createContext","displayName","useComposableParents","context","useContext","createEmptyRenderer","name","useEffect","debounced","debounce","console","info","cancel","makeComposable","Component","Composable","props","parents","ComposedComponent","useComponent","useMemo","children","original","originalName"],"sources":["makeComposable.tsx"],"sourcesContent":["import React, { createContext, useContext, useEffect, useMemo } from \"react\";\nimport debounce from \"lodash.debounce\";\nimport { ComposableFC } from \"./Compose\";\nimport { useComponent } from \"./Context\";\n\nconst ComposableContext = createContext<string[]>([]);\nComposableContext.displayName = \"ComposableContext\";\n\nfunction useComposableParents() {\n const context = useContext(ComposableContext);\n if (!context) {\n return [];\n }\n\n return context;\n}\n\nconst createEmptyRenderer = (name: string): React.FC => {\n return {\n [name]: function () {\n useEffect(() => {\n // We need to debounce the log, as it sometimes only requires a single tick to get the new\n // composed component to render, and we don't want to scare developers for no reason.\n const debounced = debounce(() => {\n console.info(\n `<${name}/> is not implemented! To provide an implementation, use the <Compose/> component.`\n );\n }, 100);\n\n return () => {\n debounced.cancel();\n };\n }, []);\n\n return null;\n }\n }[name];\n};\n\nexport function makeComposable<TProps>(name: string, Component?: React.FC<TProps>) {\n if (!Component) {\n Component = createEmptyRenderer(name);\n }\n\n const Composable: ComposableFC<TProps> = props => {\n const parents = useComposableParents();\n const ComposedComponent = useComponent(Component as React.FC<TProps>);\n\n const context = useMemo(() => [...parents, name], [parents, name]);\n\n return (\n <ComposableContext.Provider value={context}>\n <ComposedComponent {...props}>{props.children}</ComposedComponent>\n </ComposableContext.Provider>\n );\n };\n\n Component.displayName = name;\n\n Composable.original = Component;\n Composable.originalName = name;\n Composable.displayName = `Composable<${name}>`;\n\n return Composable;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA;;AACA;;AAEA;;AAEA,IAAMA,iBAAiB,gBAAG,IAAAC,oBAAA,EAAwB,EAAxB,CAA1B;AACAD,iBAAiB,CAACE,WAAlB,GAAgC,mBAAhC;;AAEA,SAASC,oBAAT,GAAgC;EAC5B,IAAMC,OAAO,GAAG,IAAAC,iBAAA,EAAWL,iBAAX,CAAhB;;EACA,IAAI,CAACI,OAAL,EAAc;IACV,OAAO,EAAP;EACH;;EAED,OAAOA,OAAP;AACH;;AAED,IAAME,mBAAmB,GAAG,SAAtBA,mBAAsB,CAACC,IAAD,EAA4B;EACpD,OAAO,kCACFA,IADE,EACK,YAAY;IAChB,IAAAC,gBAAA,EAAU,YAAM;MACZ;MACA;MACA,IAAMC,SAAS,GAAG,IAAAC,eAAA,EAAS,YAAM;QAC7BC,OAAO,CAACC,IAAR,YACQL,IADR;MAGH,CAJiB,EAIf,GAJe,CAAlB;MAMA,OAAO,YAAM;QACTE,SAAS,CAACI,MAAV;MACH,CAFD;IAGH,CAZD,EAYG,EAZH;IAcA,OAAO,IAAP;EACH,CAjBE,EAkBLN,IAlBK,CAAP;AAmBH,CApBD;;AAsBO,SAASO,cAAT,CAAgCP,IAAhC,EAA8CQ,SAA9C,EAA4E;EAC/E,IAAI,CAACA,SAAL,EAAgB;IACZA,SAAS,GAAGT,mBAAmB,CAACC,IAAD,CAA/B;EACH;;EAED,IAAMS,UAAgC,GAAG,SAAnCA,UAAmC,CAAAC,KAAK,EAAI;IAC9C,IAAMC,OAAO,GAAGf,oBAAoB,EAApC;IACA,IAAMgB,iBAAiB,GAAG,IAAAC,qBAAA,EAAaL,SAAb,CAA1B;IAEA,IAAMX,OAAO,GAAG,IAAAiB,cAAA,EAAQ;MAAA,kDAAUH,OAAV,IAAmBX,IAAnB;IAAA,CAAR,EAAkC,CAACW,OAAD,EAAUX,IAAV,CAAlC,CAAhB;IAEA,oBACI,6BAAC,iBAAD,CAAmB,QAAnB;MAA4B,KAAK,EAAEH;IAAnC,gBACI,6BAAC,iBAAD,EAAuBa,KAAvB,EAA+BA,KAAK,CAACK,QAArC,CADJ,CADJ;EAKH,CAXD;;EAaAP,SAAS,CAACb,WAAV,GAAwBK,IAAxB;EAEAS,UAAU,CAACO,QAAX,GAAsBR,SAAtB;EACAC,UAAU,CAACQ,YAAX,GAA0BjB,IAA1B;EACAS,UAAU,CAACd,WAAX,wBAAuCK,IAAvC;EAEA,OAAOS,UAAP;AACH"}
1
+ {"version":3,"file":"makeComposable.js","sources":["../src/makeComposable.tsx"],"sourcesContent":["import { createContext } from \"react\";\nimport type { GenericComponent } from \"~/types.js\";\nimport { makeDecoratable } from \"~/makeDecoratable.js\";\n\nconst ComposableContext = createContext<string[]>([]);\nComposableContext.displayName = \"ComposableContext\";\n\nconst nullRenderer = () => null;\n\n/**\n * @deprecated Use `makeDecoratable` instead.\n */\nexport function makeComposable<T extends GenericComponent>(name: string, Component?: T) {\n return makeDecoratable(name, Component ?? nullRenderer);\n}\n"],"names":["ComposableContext","createContext","nullRenderer","makeComposable","name","Component","makeDecoratable"],"mappings":";;AAIA,MAAMA,oBAAoB,WAAHA,GAAGC,cAAwB,EAAE;AACpDD,kBAAkB,WAAW,GAAG;AAEhC,MAAME,eAAe,IAAM;AAKpB,SAASC,eAA2CC,IAAY,EAAEC,SAAa;IAClF,OAAOC,gBAAgBF,MAAMC,aAAaH;AAC9C"}
@@ -0,0 +1,31 @@
1
+ import React from "react";
2
+ import type { DecoratableComponent, DecoratableHook, GenericComponent, GenericHook } from "./types.js";
3
+ declare function makeDecoratableComponent<T extends GenericComponent>(name: string, Component?: T): T & {
4
+ original: T;
5
+ originalName: string;
6
+ displayName: string;
7
+ } & {
8
+ original: T & {
9
+ original: T;
10
+ originalName: string;
11
+ displayName: string;
12
+ };
13
+ originalName: string;
14
+ displayName: string;
15
+ } & {
16
+ createDecorator: (decorator: import("~/types.js").ComponentDecorator<import("./createDecorator.js").GetDecoratee<DecoratableComponent<T & {
17
+ original: T;
18
+ originalName: string;
19
+ displayName: string;
20
+ }>>>) => (props: unknown) => React.JSX.Element;
21
+ };
22
+ export declare function makeDecoratableHook<T extends GenericHook>(hook: T): GenericHook<import("./createDecorator.js").GetDecorateeParams<import("./createDecorator.js").GetDecoratee<DecoratableHook<T>>>, ReturnType<import("./createDecorator.js").GetDecoratee<DecoratableHook<T>>>> & {
23
+ original: GenericHook<import("./createDecorator.js").GetDecorateeParams<import("./createDecorator.js").GetDecoratee<DecoratableHook<T>>>, ReturnType<import("./createDecorator.js").GetDecoratee<DecoratableHook<T>>>>;
24
+ originalName: string;
25
+ } & {
26
+ createDecorator: (decorator: import("~/types.js").Decorator<import("./createDecorator.js").GetDecoratee<DecoratableHook<T>>>) => () => React.JSX.Element;
27
+ };
28
+ export declare function createVoidComponent<T>(): (props: T) => React.JSX.Element | null;
29
+ export declare function makeDecoratable<T extends GenericHook>(hook: T): ReturnType<typeof makeDecoratableHook<T>>;
30
+ export declare function makeDecoratable<T extends GenericComponent>(name: string, Component: T): ReturnType<typeof makeDecoratableComponent<T>>;
31
+ export {};
@@ -0,0 +1,90 @@
1
+ import react, { createContext, useContext, useMemo } from "react";
2
+ import { useComponent } from "./Context.js";
3
+ import { withDecoratorFactory, withHookDecoratorFactory } from "./decorators.js";
4
+ class DecoratableErrorBoundary extends react.Component {
5
+ constructor(props){
6
+ super(props);
7
+ this.state = {
8
+ hasError: false,
9
+ error: void 0
10
+ };
11
+ }
12
+ static getDerivedStateFromError(error) {
13
+ return {
14
+ hasError: true,
15
+ error
16
+ };
17
+ }
18
+ componentDidCatch(error, errorInfo) {
19
+ console.groupCollapsed(`%cCOMPONENT ERROR%c: "${this.props.name}" failed to render.`, "color:red", "color:default");
20
+ console.error(error, errorInfo);
21
+ console.groupEnd();
22
+ }
23
+ render() {
24
+ if (this.state.hasError) return /*#__PURE__*/ react.createElement("div", {
25
+ style: {
26
+ padding: "8px 12px",
27
+ border: "1px solid #e53e3e",
28
+ borderRadius: 4,
29
+ background: "#fff5f5",
30
+ color: "#c53030",
31
+ fontSize: 13
32
+ }
33
+ }, /*#__PURE__*/ react.createElement("strong", null, this.props.name), ": ", this.state.error?.message);
34
+ return this.props.children;
35
+ }
36
+ }
37
+ const ComposableContext = /*#__PURE__*/ createContext([]);
38
+ ComposableContext.displayName = "ComposableContext";
39
+ function useComposableParents() {
40
+ const context = useContext(ComposableContext);
41
+ if (!context) return [];
42
+ return context;
43
+ }
44
+ const nullRenderer = ()=>null;
45
+ function makeDecoratableComponent(name, Component = nullRenderer) {
46
+ const Decoratable = (props)=>{
47
+ const parents = useComposableParents();
48
+ const ComposedComponent = useComponent(Component);
49
+ const context = useMemo(()=>[
50
+ ...parents,
51
+ name
52
+ ], [
53
+ parents,
54
+ name
55
+ ]);
56
+ return /*#__PURE__*/ react.createElement(ComposableContext.Provider, {
57
+ value: context
58
+ }, /*#__PURE__*/ react.createElement(DecoratableErrorBoundary, {
59
+ name: name
60
+ }, /*#__PURE__*/ react.createElement(ComposedComponent, props, props.children)));
61
+ };
62
+ const staticProps = {
63
+ original: Component,
64
+ originalName: name,
65
+ displayName: `Decoratable<${name}>`
66
+ };
67
+ return withDecoratorFactory()(Object.assign(Decoratable, staticProps));
68
+ }
69
+ function makeDecoratableHook(hook) {
70
+ const decoratableHook = (params)=>{
71
+ const composedHook = useComponent(hook);
72
+ return composedHook(params);
73
+ };
74
+ decoratableHook.original = hook;
75
+ return withHookDecoratorFactory()(decoratableHook);
76
+ }
77
+ function createVoidComponent() {
78
+ return (props)=>null;
79
+ }
80
+ function makeDecoratable(hookOrName, Component) {
81
+ if (Component) {
82
+ const component = makeDecoratableComponent(hookOrName, /*#__PURE__*/ react.memo(Component));
83
+ component.original.displayName = hookOrName;
84
+ return component;
85
+ }
86
+ return makeDecoratableHook(hookOrName);
87
+ }
88
+ export { createVoidComponent, makeDecoratable, makeDecoratableHook };
89
+
90
+ //# sourceMappingURL=makeDecoratable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"makeDecoratable.js","sources":["../src/makeDecoratable.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo } from \"react\";\nimport type { ErrorInfo } from \"react\";\nimport { useComponent } from \"./Context.js\";\nimport type {\n DecoratableComponent,\n DecoratableHook,\n GenericComponent,\n GenericHook\n} from \"~/types.js\";\nimport { withDecoratorFactory, withHookDecoratorFactory } from \"~/decorators.js\";\n\ninterface ErrorBoundaryProps {\n name: string;\n children: React.ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | undefined;\n}\n\nclass DecoratableErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: undefined };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n override componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n console.groupCollapsed(\n `%cCOMPONENT ERROR%c: \"${this.props.name}\" failed to render.`,\n \"color:red\",\n \"color:default\"\n );\n console.error(error, errorInfo);\n console.groupEnd();\n }\n\n override render() {\n if (this.state.hasError) {\n return (\n <div\n style={{\n padding: \"8px 12px\",\n border: \"1px solid #e53e3e\",\n borderRadius: 4,\n background: \"#fff5f5\",\n color: \"#c53030\",\n fontSize: 13\n }}\n >\n <strong>{this.props.name}</strong>: {this.state.error?.message}\n </div>\n );\n }\n return this.props.children;\n }\n}\n\nconst ComposableContext = createContext<string[]>([]);\nComposableContext.displayName = \"ComposableContext\";\n\nfunction useComposableParents() {\n const context = useContext(ComposableContext);\n if (!context) {\n return [];\n }\n\n return context;\n}\n\nconst nullRenderer = () => null;\n\nfunction makeDecoratableComponent<T extends GenericComponent>(\n name: string,\n Component: T = nullRenderer as unknown as T\n) {\n const Decoratable = (props: React.ComponentProps<T>): React.JSX.Element | null => {\n const parents = useComposableParents();\n const ComposedComponent = useComponent(Component) as GenericComponent<\n React.ComponentProps<T>\n >;\n\n const context = useMemo(() => [...parents, name], [parents, name]);\n\n return (\n <ComposableContext.Provider value={context}>\n <DecoratableErrorBoundary name={name}>\n <ComposedComponent {...props}>{props.children}</ComposedComponent>\n </DecoratableErrorBoundary>\n </ComposableContext.Provider>\n );\n };\n\n const staticProps = {\n original: Component,\n originalName: name,\n displayName: `Decoratable<${name}>`\n };\n\n return withDecoratorFactory()(\n Object.assign(Decoratable, staticProps) as DecoratableComponent<\n typeof Component & typeof staticProps\n >\n );\n}\n\nexport function makeDecoratableHook<T extends GenericHook>(hook: T) {\n const decoratableHook = (params: Parameters<T>) => {\n const composedHook = useComponent(hook);\n\n return composedHook(params) as DecoratableHook<T>;\n };\n\n decoratableHook.original = hook;\n\n return withHookDecoratorFactory()(decoratableHook as DecoratableHook<T>);\n}\n\nexport function createVoidComponent<T>() {\n // oxlint-disable-next-line typescript/no-unused-vars\n return (props: T): React.JSX.Element | null => {\n return null;\n };\n}\n\nexport function makeDecoratable<T extends GenericHook>(\n hook: T\n): ReturnType<typeof makeDecoratableHook<T>>;\nexport function makeDecoratable<T extends GenericComponent>(\n name: string,\n Component: T\n): ReturnType<typeof makeDecoratableComponent<T>>;\nexport function makeDecoratable(hookOrName: any, Component?: any) {\n if (Component) {\n const component = makeDecoratableComponent(hookOrName, React.memo(Component));\n component.original.displayName = hookOrName;\n return component;\n }\n\n return makeDecoratableHook(hookOrName);\n}\n"],"names":["DecoratableErrorBoundary","React","props","undefined","error","errorInfo","console","ComposableContext","createContext","useComposableParents","context","useContext","nullRenderer","makeDecoratableComponent","name","Component","Decoratable","parents","ComposedComponent","useComponent","useMemo","staticProps","withDecoratorFactory","Object","makeDecoratableHook","hook","decoratableHook","params","composedHook","withHookDecoratorFactory","createVoidComponent","makeDecoratable","hookOrName","component"],"mappings":";;;AAqBA,MAAMA,iCAAiCC,MAAAA,SAAe;IAClD,YAAYC,KAAyB,CAAE;QACnC,KAAK,CAACA;QACN,IAAI,CAAC,KAAK,GAAG;YAAE,UAAU;YAAO,OAAOC;QAAU;IACrD;IAEA,OAAO,yBAAyBC,KAAY,EAAsB;QAC9D,OAAO;YAAE,UAAU;YAAMA;QAAM;IACnC;IAES,kBAAkBA,KAAY,EAAEC,SAAoB,EAAE;QAC3DC,QAAQ,cAAc,CAClB,CAAC,sBAAsB,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,EAC7D,aACA;QAEJA,QAAQ,KAAK,CAACF,OAAOC;QACrBC,QAAQ,QAAQ;IACpB;IAES,SAAS;QACd,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EACnB,OAAO,WAAP,GACI,oBAAC;YACG,OAAO;gBACH,SAAS;gBACT,QAAQ;gBACR,cAAc;gBACd,YAAY;gBACZ,OAAO;gBACP,UAAU;YACd;yBAEA,oBAAC,gBAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,GAAU,MAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;QAInE,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ;IAC9B;AACJ;AAEA,MAAMC,oBAAoB,WAAHA,GAAGC,cAAwB,EAAE;AACpDD,kBAAkB,WAAW,GAAG;AAEhC,SAASE;IACL,MAAMC,UAAUC,WAAWJ;IAC3B,IAAI,CAACG,SACD,OAAO,EAAE;IAGb,OAAOA;AACX;AAEA,MAAME,eAAe,IAAM;AAE3B,SAASC,yBACLC,IAAY,EACZC,YAAeH,YAA4B;IAE3C,MAAMI,cAAc,CAACd;QACjB,MAAMe,UAAUR;QAChB,MAAMS,oBAAoBC,aAAaJ;QAIvC,MAAML,UAAUU,QAAQ,IAAM;mBAAIH;gBAASH;aAAK,EAAE;YAACG;YAASH;SAAK;QAEjE,OAAO,WAAP,GACI,oBAACP,kBAAkB,QAAQ;YAAC,OAAOG;yBAC/B,oBAACV,0BAAwBA;YAAC,MAAMc;yBAC5B,oBAACI,mBAAsBhB,OAAQA,MAAM,QAAQ;IAI7D;IAEA,MAAMmB,cAAc;QAChB,UAAUN;QACV,cAAcD;QACd,aAAa,CAAC,YAAY,EAAEA,KAAK,CAAC,CAAC;IACvC;IAEA,OAAOQ,uBACHC,OAAO,MAAM,CAACP,aAAaK;AAInC;AAEO,SAASG,oBAA2CC,IAAO;IAC9D,MAAMC,kBAAkB,CAACC;QACrB,MAAMC,eAAeT,aAAaM;QAElC,OAAOG,aAAaD;IACxB;IAEAD,gBAAgB,QAAQ,GAAGD;IAE3B,OAAOI,2BAA2BH;AACtC;AAEO,SAASI;IAEZ,OAAO,CAAC5B,QACG;AAEf;AASO,SAAS6B,gBAAgBC,UAAe,EAAEjB,SAAe;IAC5D,IAAIA,WAAW;QACX,MAAMkB,YAAYpB,yBAAyBmB,YAAY,WAAZA,GAAY/B,MAAAA,IAAU,CAACc;QAClEkB,UAAU,QAAQ,CAAC,WAAW,GAAGD;QACjC,OAAOC;IACX;IAEA,OAAOT,oBAAoBQ;AAC/B"}
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "@webiny/react-composition",
3
- "version": "0.0.0-unstable.78f581c1d2",
4
- "main": "index.js",
3
+ "version": "0.0.0-unstable.7be00a75a9",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": "./index.js",
7
+ "./*": "./*"
8
+ },
5
9
  "repository": {
6
10
  "type": "git",
7
11
  "url": "https://github.com/webiny/webiny-js.git"
@@ -14,29 +18,20 @@
14
18
  ],
15
19
  "license": "MIT",
16
20
  "dependencies": {
17
- "@babel/runtime": "7.19.0",
18
- "@types/react": "17.0.39",
19
- "lodash.debounce": "4.0.8",
20
- "react": "17.0.2",
21
- "react-dom": "17.0.2"
21
+ "@types/react": "18.3.29",
22
+ "react": "18.3.1",
23
+ "react-dom": "18.3.1"
22
24
  },
23
25
  "devDependencies": {
24
- "@babel/cli": "^7.19.3",
25
- "@babel/core": "^7.19.3",
26
- "@babel/preset-env": "^7.19.4",
27
- "@babel/preset-typescript": "^7.18.6",
28
- "@webiny/cli": "^0.0.0-unstable.78f581c1d2",
29
- "@webiny/project-utils": "^0.0.0-unstable.78f581c1d2",
30
- "ttypescript": "^1.5.13",
31
- "typescript": "4.7.4"
26
+ "@testing-library/react": "16.3.2",
27
+ "@webiny/build-tools": "0.0.0-unstable.7be00a75a9",
28
+ "typescript": "6.0.3",
29
+ "vitest": "4.1.7"
32
30
  },
33
31
  "publishConfig": {
34
- "access": "public",
35
- "directory": "dist"
36
- },
37
- "scripts": {
38
- "build": "yarn webiny run build",
39
- "watch": "yarn webiny run watch"
32
+ "access": "public"
40
33
  },
41
- "gitHead": "78f581c1d2e5e6936aa11b9452a66d2a3652a1b2"
34
+ "webiny": {
35
+ "publishFrom": "dist"
36
+ }
42
37
  }
package/types.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ import type React from "react";
2
+ export type GenericHook<TParams = any, TReturn = any> = (...args: TParams[]) => TReturn;
3
+ export type GenericComponent<T = any> = React.FunctionComponent<T>;
4
+ export type ComposedFunction = GenericHook;
5
+ export type Decorator<T> = (decoratee: T) => T;
6
+ /**
7
+ * Some decoratable components will always return `null`, by design.
8
+ * To allow you to decorate these components, we must tell TS that the decorator is allowed to return not just `null`
9
+ * (which is inferred from the component type), but also a JSX.Element.
10
+ */
11
+ export type ComponentDecorator<T> = (decoratee: T) => CanReturnNullOrElement<T>;
12
+ /**
13
+ * @deprecated
14
+ */
15
+ export type ComposableFC<T> = T & {
16
+ displayName?: string;
17
+ original: T;
18
+ originalName: string;
19
+ };
20
+ export type Enumerable<T> = T extends Array<infer D> ? Array<D> : never;
21
+ export type ComposeWith = Decorator<GenericComponent> | Decorator<GenericComponent>[] | Decorator<GenericHook> | Decorator<GenericHook>[];
22
+ export type DecoratableHook<T extends GenericHook = GenericHook> = T & {
23
+ original: T;
24
+ originalName: string;
25
+ };
26
+ export type DecoratableComponent<T = GenericComponent> = T & {
27
+ original: T;
28
+ originalName: string;
29
+ displayName: string;
30
+ };
31
+ export type Decoratable = DecoratableComponent | DecoratableHook;
32
+ /**
33
+ * @internal Add `null` to the ReturnType of the given function.
34
+ */
35
+ export type CanReturnNullOrElement<T> = T extends (...args: any) => any ? (...args: Parameters<T>) => React.JSX.Element | null : never;
package/types.js ADDED
File without changes
@@ -1,3 +0,0 @@
1
- import React, { ComponentProps } from "react";
2
- import { ComposableFC, HigherOrderComponent } from "./index";
3
- export declare function createComponentPlugin<T extends ComposableFC<ComponentProps<T>>>(Base: T, hoc: HigherOrderComponent<ComponentProps<T>>): React.FC;
@@ -1,24 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.createComponentPlugin = createComponentPlugin;
9
-
10
- var _react = _interopRequireDefault(require("react"));
11
-
12
- var _index = require("./index");
13
-
14
- function createComponentPlugin(Base, hoc) {
15
- var ComponentPlugin = function ComponentPlugin() {
16
- return /*#__PURE__*/_react.default.createElement(_index.Compose, {
17
- component: Base,
18
- with: hoc
19
- });
20
- };
21
-
22
- ComponentPlugin.displayName = Base.displayName;
23
- return ComponentPlugin;
24
- }
@@ -1 +0,0 @@
1
- {"version":3,"names":["createComponentPlugin","Base","hoc","ComponentPlugin","displayName"],"sources":["createComponentPlugin.tsx"],"sourcesContent":["import React, { ComponentProps } from \"react\";\nimport { ComposableFC, Compose, HigherOrderComponent } from \"./index\";\n\nexport function createComponentPlugin<T extends ComposableFC<ComponentProps<T>>>(\n Base: T,\n hoc: HigherOrderComponent<ComponentProps<T>>\n): React.FC {\n const ComponentPlugin = () => <Compose component={Base} with={hoc} />;\n ComponentPlugin.displayName = Base.displayName;\n return ComponentPlugin;\n}\n"],"mappings":";;;;;;;;;AAAA;;AACA;;AAEO,SAASA,qBAAT,CACHC,IADG,EAEHC,GAFG,EAGK;EACR,IAAMC,eAAe,GAAG,SAAlBA,eAAkB;IAAA,oBAAM,6BAAC,cAAD;MAAS,SAAS,EAAEF,IAApB;MAA0B,IAAI,EAAEC;IAAhC,EAAN;EAAA,CAAxB;;EACAC,eAAe,CAACC,WAAhB,GAA8BH,IAAI,CAACG,WAAnC;EACA,OAAOD,eAAP;AACH"}
package/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./Context\";\nexport * from \"./Compose\";\nexport * from \"./makeComposable\";\nexport * from \"./createComponentPlugin\";\n"],"mappings":";;;;;;AAAA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA;;AACA;;AAAA;EAAA;EAAA;EAAA;IAAA;IAAA;MAAA;IAAA;EAAA;AAAA"}