@cleanweb/react 1.1.1-beta.8 → 2.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/README.md +242 -187
- package/README.old.md +342 -0
- package/build/base/merged-state.d.ts +1 -0
- package/build/base/merged-state.js +3 -2
- package/build/base/methods.d.ts +40 -7
- package/build/base/methods.js +45 -81
- package/build/base/state/class-types.d.ts +17 -0
- package/build/base/state/class-types.js +2 -0
- package/build/base/state/class.d.ts +14 -0
- package/build/base/{state.js → state/class.js} +4 -55
- package/build/base/state/hook-types.d.ts +11 -0
- package/build/base/state/hook-types.js +2 -0
- package/build/base/state/hooks.d.ts +11 -0
- package/build/base/state/hooks.js +57 -0
- package/build/base/state/index.d.ts +4 -0
- package/build/base/state/index.js +9 -0
- package/build/classy/class/index.d.ts +102 -0
- package/build/classy/class/index.js +147 -0
- package/build/classy/class/types/class/instance.d.ts +12 -0
- package/build/classy/class/types/class/instance.js +2 -0
- package/build/classy/class/types/class/static.d.ts +9 -0
- package/build/classy/class/types/class/static.js +12 -0
- package/build/classy/class/types/extractor.d.ts +6 -0
- package/build/classy/class/types/extractor.js +2 -0
- package/build/classy/class/utils/function-name.d.ts +2 -0
- package/build/classy/class/utils/function-name.js +17 -0
- package/build/classy/class/utils/rerender.d.ts +1 -0
- package/build/classy/class/utils/rerender.js +11 -0
- package/build/classy/class/utils/use-component/index.d.ts +6 -0
- package/build/classy/class/utils/use-component/index.js +17 -0
- package/build/classy/class/utils/use-component/types.d.ts +22 -0
- package/build/classy/class/utils/use-component/types.js +2 -0
- package/build/classy/instance/index.d.ts +94 -0
- package/build/classy/{instance.js → instance/index.js} +62 -33
- package/build/classy/instance/mount-callbacks.d.ts +4 -0
- package/build/classy/instance/mount-callbacks.js +30 -0
- package/build/classy/instance/types/hook.d.ts +16 -0
- package/build/classy/instance/types/hook.js +2 -0
- package/build/classy/instance/types/instance.d.ts +11 -0
- package/build/classy/instance/types/instance.js +2 -0
- package/build/classy/instance/types/static.d.ts +11 -0
- package/build/classy/instance/types/static.js +17 -0
- package/build/classy/logic/index.d.ts +42 -0
- package/build/classy/logic/index.js +122 -0
- package/build/classy/logic/types/hook.d.ts +24 -0
- package/build/classy/logic/types/hook.js +2 -0
- package/build/classy/logic/types/instance.d.ts +18 -0
- package/build/classy/logic/types/instance.js +2 -0
- package/build/classy/logic/types/static.d.ts +17 -0
- package/build/classy/logic/types/static.js +2 -0
- package/build/globals.d.ts +23 -33
- package/build/globals.js +2 -20
- package/build/index.d.ts +1 -1
- package/build/index.js +2 -1
- package/build/tsconfig.json +3 -0
- package/package.json +8 -6
- package/build/base/state.d.ts +0 -29
- package/build/classy/class.d.ts +0 -22
- package/build/classy/class.js +0 -118
- package/build/classy/instance.d.ts +0 -60
- package/build/classy/logic.d.ts +0 -20
- package/build/classy/logic.js +0 -79
- package/build/globals.private.d.ts +0 -44
- package/build/globals.private.js +0 -34
@@ -0,0 +1,11 @@
|
|
1
|
+
import { CleanStateBase } from './class';
|
2
|
+
export type TStateData = object & {
|
3
|
+
[Key in keyof CleanStateBase<{}>]?: never;
|
4
|
+
};
|
5
|
+
export type TCleanState<TState extends TStateData> = (CleanStateBase<TState> & Omit<TState, keyof CleanStateBase<{}>>);
|
6
|
+
export type ExtractCleanStateData<YourCleanState extends CleanStateBase<{}>> = Omit<YourCleanState, keyof CleanStateBase<{}>>;
|
7
|
+
type StateInitFunction = (...args: any[]) => object;
|
8
|
+
type StateInit = object | StateInitFunction;
|
9
|
+
export type TInitialState<Initializer extends StateInit> = Initializer extends (...args: any[]) => (infer TState extends object) ? TState : Initializer;
|
10
|
+
export type TUseCleanState = <TInit extends StateInit>(_initialState: TInit, ...props: TInit extends (...args: infer TProps extends any[]) => (infer TState extends object) ? TProps : []) => TCleanState<TInitialState<TInit>>;
|
11
|
+
export {};
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { TUseCleanState } from './hook-types';
|
2
|
+
/**
|
3
|
+
* Returns a value that is false before the component has been mounted,
|
4
|
+
* then true during all subsequent rerenders.
|
5
|
+
*/
|
6
|
+
export declare const useMountState: () => boolean;
|
7
|
+
/**
|
8
|
+
* Creates a state object, which includes the provided values, and helper methods for
|
9
|
+
* updating those values and automatically rerendering your component's UI accordingly.
|
10
|
+
*/
|
11
|
+
export declare const useCleanState: TUseCleanState;
|
@@ -0,0 +1,57 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.useCleanState = exports.useMountState = void 0;
|
4
|
+
var react_1 = require("react");
|
5
|
+
var class_1 = require("./class");
|
6
|
+
/**
|
7
|
+
* Returns a value that is false before the component has been mounted,
|
8
|
+
* then true during all subsequent rerenders.
|
9
|
+
*/
|
10
|
+
var useMountState = function () {
|
11
|
+
/**
|
12
|
+
* This must not be a stateful value. It should not be the cause of a rerender.
|
13
|
+
* It merely provides information about the render count,
|
14
|
+
* without influencing that count itself.
|
15
|
+
* So `mounted` should never be set with `useState`.
|
16
|
+
*/
|
17
|
+
var mounted = (0, react_1.useRef)(false);
|
18
|
+
(0, react_1.useEffect)(function () {
|
19
|
+
mounted.current = true;
|
20
|
+
}, []);
|
21
|
+
return mounted.current;
|
22
|
+
};
|
23
|
+
exports.useMountState = useMountState;
|
24
|
+
/**
|
25
|
+
* Creates a state object, which includes the provided values, and helper methods for
|
26
|
+
* updating those values and automatically rerendering your component's UI accordingly.
|
27
|
+
*/
|
28
|
+
var useCleanState = function (_initialState) {
|
29
|
+
var props = [];
|
30
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
31
|
+
props[_i - 1] = arguments[_i];
|
32
|
+
}
|
33
|
+
var initialState = typeof _initialState === 'function'
|
34
|
+
? (0, react_1.useMemo)(function () { return _initialState.apply(void 0, props); }, [])
|
35
|
+
: _initialState;
|
36
|
+
;
|
37
|
+
var cleanState = (0, react_1.useRef)((0, react_1.useMemo)(function () {
|
38
|
+
return new class_1.CleanState(initialState);
|
39
|
+
}, [])).current;
|
40
|
+
class_1.CleanState.update.call(cleanState);
|
41
|
+
return cleanState;
|
42
|
+
};
|
43
|
+
exports.useCleanState = useCleanState;
|
44
|
+
// Should be valid.
|
45
|
+
// useCleanState((a: number) => ({b: a.toString(), q: 1}), 6);
|
46
|
+
// useCleanState((a: boolean) => ({b: a.toString()}), true);
|
47
|
+
// useCleanState((a: number, c?: string) => ({ b: `${a}` }), 6);
|
48
|
+
// useCleanState((a: number, c?: string) => ({ b: `${a}` }), 6, 'word');
|
49
|
+
// useCleanState((a: number, c: string) => ({ b: a + c, f: true }), 6, 'text');
|
50
|
+
// useCleanState({ d: 5000 });
|
51
|
+
// Should fail.
|
52
|
+
// useCleanState((a: number) => ({b: a.toString(), q: 1}), 6, false);
|
53
|
+
// useCleanState((a: boolean) => ({b: a.toString()}));
|
54
|
+
// useCleanState((a: number, c?: string) => ({ b: `${a}` }), '6');
|
55
|
+
// useCleanState((a: number, c?: string) => ({ b: `${a}` }));
|
56
|
+
// useCleanState((a: number, c: string) => ({ b: a + c, f: true }), 6, 7);
|
57
|
+
// useCleanState({ d: 5000 }, true);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.useMountState = exports.useCleanState = exports.CleanState = void 0;
|
4
|
+
require("../../globals");
|
5
|
+
var class_1 = require("./class");
|
6
|
+
Object.defineProperty(exports, "CleanState", { enumerable: true, get: function () { return class_1.CleanState; } });
|
7
|
+
var hooks_1 = require("./hooks");
|
8
|
+
Object.defineProperty(exports, "useCleanState", { enumerable: true, get: function () { return hooks_1.useCleanState; } });
|
9
|
+
Object.defineProperty(exports, "useMountState", { enumerable: true, get: function () { return hooks_1.useMountState; } });
|
@@ -0,0 +1,102 @@
|
|
1
|
+
import type { TStateData } from '../../base';
|
2
|
+
import type { Extractor } from './types/extractor';
|
3
|
+
import { ComponentInstance } from '../instance';
|
4
|
+
type o = object;
|
5
|
+
/**
|
6
|
+
* A superset of {@link ComponentInstance} that allows defining your
|
7
|
+
* component's JSX template directly inside the class.
|
8
|
+
*
|
9
|
+
* This is designed to closely resemble the old {@link React.Component} class,
|
10
|
+
* making it easier to migrate older class components to the newer hooks-based system
|
11
|
+
* with little to no changes to their existing semantics/implementation.
|
12
|
+
*/
|
13
|
+
export declare class ClassComponent<TProps extends o = WeakEmptyObject, TState extends TStateData = WeakEmptyObject> extends ComponentInstance<TProps, TState> {
|
14
|
+
/**
|
15
|
+
* Analogous to {@link React.Component.render}. A function that returns
|
16
|
+
* your component's JSX template.
|
17
|
+
*
|
18
|
+
* You should place most logic that would usually go here
|
19
|
+
* in {@link ComponentInstance.beforeRender | `beforeRender`} instead.
|
20
|
+
* This helps to separate concerns and keep the template itself clean.
|
21
|
+
*
|
22
|
+
* ******
|
23
|
+
*
|
24
|
+
* Ideally the template method should only be concerned with defining the HTML/JSX structure of
|
25
|
+
* your component's UI. This may include destructuring nested instance members
|
26
|
+
* into more easily accessible local variables, or some simple transformation of data from props/state
|
27
|
+
* into a more appropriate format for display.
|
28
|
+
*
|
29
|
+
* ******
|
30
|
+
*
|
31
|
+
* @example < caption>Using a template function that returns JSX.</ caption>
|
32
|
+
*
|
33
|
+
* ```tsx
|
34
|
+
* template = () => {
|
35
|
+
* const { title } = this.props;
|
36
|
+
*
|
37
|
+
* return (
|
38
|
+
* <h1>
|
39
|
+
* {this.props.title}
|
40
|
+
* </h1>
|
41
|
+
* );
|
42
|
+
* }
|
43
|
+
* ```
|
44
|
+
*/
|
45
|
+
template: (context: this['templateContext']) => (React.JSX.Element | null);
|
46
|
+
/**
|
47
|
+
* Manually trigger a rerender of your component.
|
48
|
+
* You should rarely ever need this. But if you are migrating
|
49
|
+
* an older React.Component class, this should provide similar functionality
|
50
|
+
* to the {@link React.Component.forceUpdate | `forceUpdate`} method provided there.
|
51
|
+
*
|
52
|
+
* Note that the callback argument is currently not supported.
|
53
|
+
*/
|
54
|
+
readonly forceUpdate: VoidFunction;
|
55
|
+
/*************************************
|
56
|
+
* Function Component Extractor *
|
57
|
+
**************************************/
|
58
|
+
/**
|
59
|
+
* Extract a Function Component (FC) which can be used to render
|
60
|
+
* your ClassComponent just like any other React component.
|
61
|
+
*
|
62
|
+
* Each JSX reference to the returned component will render with
|
63
|
+
* a separate instance of your class.
|
64
|
+
*
|
65
|
+
* So you only need to call `YourClassComponent.FC()` once, then use the returned
|
66
|
+
* function component as many times as you need.
|
67
|
+
*
|
68
|
+
* It is recommended to store this returned value as a static member of
|
69
|
+
* your ClassComponent. While this value may be given any name, the name
|
70
|
+
* RC (for "React Component") is the recommended convention.
|
71
|
+
*
|
72
|
+
* @example <caption>Calling FC in your ClassComponent</caption>
|
73
|
+
* class Button extends ClassComponent {
|
74
|
+
* static readonly RC = this.FC();
|
75
|
+
* // Because of the static keyword, `this` here refers to the class itself, same as calling `Button.FC()`.
|
76
|
+
* }
|
77
|
+
*
|
78
|
+
* // Render with `<Button.RC />`, or export RC to use the component in other files.
|
79
|
+
* export default Button.RC;
|
80
|
+
*/
|
81
|
+
static readonly extract: Extractor;
|
82
|
+
/** @see {@link ClassComponent.extract} */
|
83
|
+
static readonly FC: Extractor;
|
84
|
+
}
|
85
|
+
export { ClassComponent as Component };
|
86
|
+
/** /
|
87
|
+
testing: {
|
88
|
+
const a: object = {b: ''};
|
89
|
+
|
90
|
+
type t = keyof typeof a;
|
91
|
+
|
92
|
+
class MyComponentLogic extends ClassComponent<{}, {a: ''}> {
|
93
|
+
static getInitialState = () => ({a: '' as const});
|
94
|
+
// a = () => this.hooks.a = '';
|
95
|
+
|
96
|
+
useHooks = () => {
|
97
|
+
this.state.a;
|
98
|
+
};
|
99
|
+
};
|
100
|
+
|
101
|
+
const Template = MyComponentLogic.FC();
|
102
|
+
}/**/
|
@@ -0,0 +1,147 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
3
|
+
var extendStatics = function (d, b) {
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
7
|
+
return extendStatics(d, b);
|
8
|
+
};
|
9
|
+
return function (d, b) {
|
10
|
+
if (typeof b !== "function" && b !== null)
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
12
|
+
extendStatics(d, b);
|
13
|
+
function __() { this.constructor = d; }
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
15
|
+
};
|
16
|
+
})();
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
18
|
+
exports.Component = exports.ClassComponent = void 0;
|
19
|
+
var react_1 = require("react");
|
20
|
+
var instance_1 = require("../instance");
|
21
|
+
var function_name_1 = require("./utils/function-name");
|
22
|
+
var rerender_1 = require("./utils/rerender");
|
23
|
+
/**
|
24
|
+
* A superset of {@link ComponentInstance} that allows defining your
|
25
|
+
* component's JSX template directly inside the class.
|
26
|
+
*
|
27
|
+
* This is designed to closely resemble the old {@link React.Component} class,
|
28
|
+
* making it easier to migrate older class components to the newer hooks-based system
|
29
|
+
* with little to no changes to their existing semantics/implementation.
|
30
|
+
*/
|
31
|
+
var ClassComponent = /** @class */ (function (_super) {
|
32
|
+
__extends(ClassComponent, _super);
|
33
|
+
function ClassComponent() {
|
34
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
35
|
+
/**
|
36
|
+
* Analogous to {@link React.Component.render}. A function that returns
|
37
|
+
* your component's JSX template.
|
38
|
+
*
|
39
|
+
* You should place most logic that would usually go here
|
40
|
+
* in {@link ComponentInstance.beforeRender | `beforeRender`} instead.
|
41
|
+
* This helps to separate concerns and keep the template itself clean.
|
42
|
+
*
|
43
|
+
* ******
|
44
|
+
*
|
45
|
+
* Ideally the template method should only be concerned with defining the HTML/JSX structure of
|
46
|
+
* your component's UI. This may include destructuring nested instance members
|
47
|
+
* into more easily accessible local variables, or some simple transformation of data from props/state
|
48
|
+
* into a more appropriate format for display.
|
49
|
+
*
|
50
|
+
* ******
|
51
|
+
*
|
52
|
+
* @example < caption>Using a template function that returns JSX.</ caption>
|
53
|
+
*
|
54
|
+
* ```tsx
|
55
|
+
* template = () => {
|
56
|
+
* const { title } = this.props;
|
57
|
+
*
|
58
|
+
* return (
|
59
|
+
* <h1>
|
60
|
+
* {this.props.title}
|
61
|
+
* </h1>
|
62
|
+
* );
|
63
|
+
* }
|
64
|
+
* ```
|
65
|
+
*/
|
66
|
+
_this.template = function () { return null; };
|
67
|
+
return _this;
|
68
|
+
}
|
69
|
+
var _a;
|
70
|
+
_a = ClassComponent;
|
71
|
+
/*************************************
|
72
|
+
* Function Component Extractor *
|
73
|
+
**************************************/
|
74
|
+
/**
|
75
|
+
* Extract a Function Component (FC) which can be used to render
|
76
|
+
* your ClassComponent just like any other React component.
|
77
|
+
*
|
78
|
+
* Each JSX reference to the returned component will render with
|
79
|
+
* a separate instance of your class.
|
80
|
+
*
|
81
|
+
* So you only need to call `YourClassComponent.FC()` once, then use the returned
|
82
|
+
* function component as many times as you need.
|
83
|
+
*
|
84
|
+
* It is recommended to store this returned value as a static member of
|
85
|
+
* your ClassComponent. While this value may be given any name, the name
|
86
|
+
* RC (for "React Component") is the recommended convention.
|
87
|
+
*
|
88
|
+
* @example <caption>Calling FC in your ClassComponent</caption>
|
89
|
+
* class Button extends ClassComponent {
|
90
|
+
* static readonly RC = this.FC();
|
91
|
+
* // Because of the static keyword, `this` here refers to the class itself, same as calling `Button.FC()`.
|
92
|
+
* }
|
93
|
+
*
|
94
|
+
* // Render with `<Button.RC />`, or export RC to use the component in other files.
|
95
|
+
* export default Button.RC;
|
96
|
+
*/
|
97
|
+
ClassComponent.extract = function FC(_Component) {
|
98
|
+
var Component = _Component !== null && _Component !== void 0 ? _Component : this;
|
99
|
+
var isClassComponentType = Component.prototype instanceof _a;
|
100
|
+
if (!Component.getInitialState || !isClassComponentType)
|
101
|
+
throw new Error('Attempted to initialize ClassComponent with invalid Class type. Either pass a class that extends ClassComponent to FC (e.g `export FC(MyComponent);`), or ensure it is called as a method on a ClassComponent constructor type (e.g `export MyComponent.FC()`).');
|
102
|
+
/*************************************
|
103
|
+
* Begin Function Component *
|
104
|
+
**************************************/
|
105
|
+
/** A class-based React function component created with (@cleanweb/react).{@link ClassComponent} */
|
106
|
+
var Wrapper = function (props) {
|
107
|
+
var instance = (0, instance_1.useInstance)(Component, props);
|
108
|
+
var template = instance.template, templateContext = instance.templateContext;
|
109
|
+
var _forceUpdate;
|
110
|
+
// @ts-expect-error (Cannot assign to 'forceUpdate' because it is a read-only property.ts(2540))
|
111
|
+
instance.forceUpdate = (_forceUpdate = (0, rerender_1.useRerender)() // Moved this to separate line to allow TS errors. Use proxy local variable to regain some type checking for the assignment to `instance.forceUpdate`.
|
112
|
+
);
|
113
|
+
// Add calling component name to template function name in stack traces.
|
114
|
+
(0, react_1.useMemo)(function () {
|
115
|
+
(0, function_name_1.setFunctionName)(template, "".concat(Component.name, ".template"));
|
116
|
+
}, [template]);
|
117
|
+
return template(templateContext);
|
118
|
+
};
|
119
|
+
/**************************************
|
120
|
+
* End Function Component *
|
121
|
+
**************************************/
|
122
|
+
(0, function_name_1.setFunctionName)(Wrapper, "$".concat(Component.name, "$"));
|
123
|
+
return Wrapper;
|
124
|
+
};
|
125
|
+
/** @see {@link ClassComponent.extract} */
|
126
|
+
ClassComponent.FC = _a.extract;
|
127
|
+
return ClassComponent;
|
128
|
+
}(instance_1.ComponentInstance));
|
129
|
+
exports.ClassComponent = ClassComponent;
|
130
|
+
exports.Component = ClassComponent;
|
131
|
+
/** /
|
132
|
+
testing: {
|
133
|
+
const a: object = {b: ''};
|
134
|
+
|
135
|
+
type t = keyof typeof a;
|
136
|
+
|
137
|
+
class MyComponentLogic extends ClassComponent<{}, {a: ''}> {
|
138
|
+
static getInitialState = () => ({a: '' as const});
|
139
|
+
// a = () => this.hooks.a = '';
|
140
|
+
|
141
|
+
useHooks = () => {
|
142
|
+
this.state.a;
|
143
|
+
};
|
144
|
+
};
|
145
|
+
|
146
|
+
const Template = MyComponentLogic.FC();
|
147
|
+
}/**/
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import type { ExtractCleanStateData } from '../../../../base';
|
2
|
+
import type { InstanceOverrides as CIInstanceOverrides } from '../../../../classy/instance/types/instance';
|
3
|
+
import { ClassComponent } from '../../../../classy/class';
|
4
|
+
export type BaseClassComponent = ClassComponent<object, object>;
|
5
|
+
export type CCBaseType = ClassComponent<object, object>;
|
6
|
+
type CCFromSubType<SubType extends CCBaseType> = ClassComponent<SubType['props'], ExtractCleanStateData<SubType['state']>>;
|
7
|
+
export interface InstanceOverrides<Instance extends CCBaseType = ClassComponent> extends CIInstanceOverrides<Instance> {
|
8
|
+
}
|
9
|
+
type BaseInstance<Instance extends CCBaseType = ClassComponent> = Omit<CCFromSubType<Instance>, keyof InstanceOverrides>;
|
10
|
+
export interface IClassComponent<Instance extends CCBaseType = ClassComponent> extends BaseInstance<Instance>, InstanceOverrides<Instance> {
|
11
|
+
}
|
12
|
+
export {};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import type { StaticOverrides as CIStaticOverrides } from '../../../../classy/instance/types/static';
|
2
|
+
import type { CCBaseType } from './instance';
|
3
|
+
import { ClassComponent } from '../..';
|
4
|
+
export interface StaticOverrides<Instance extends CCBaseType = ClassComponent> extends CIStaticOverrides<Instance> {
|
5
|
+
}
|
6
|
+
type BaseStatics = Omit<typeof ClassComponent, 'prototype' | keyof StaticOverrides>;
|
7
|
+
export interface IClassComponentConstructor<Instance extends CCBaseType = ClassComponent> extends BaseStatics, StaticOverrides<Instance> {
|
8
|
+
}
|
9
|
+
export {};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
// type ComponentClassOwnStaticKeys = Exclude<
|
4
|
+
// keyof typeof ClassComponent,
|
5
|
+
// keyof IComponentInstanceClass
|
6
|
+
// >;
|
7
|
+
// type ComponentClassOwnStatics = {
|
8
|
+
// [Key in ComponentClassOwnStaticKeys]: (typeof ClassComponent)[Key];
|
9
|
+
// }
|
10
|
+
// export interface ClassComponentConstructor<
|
11
|
+
// Instance extends BaseClassComponent = ClassComponent
|
12
|
+
// > extends Constructor<Instance>, ComponentClassOwnStatics, IComponentInstanceClass<Instance> {};
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import type { VoidFunctionComponent } from 'react';
|
2
|
+
import type { BaseClassComponent } from './class/instance';
|
3
|
+
import type { IClassComponentConstructor } from './class/static';
|
4
|
+
type BaseCCConstructor = IClassComponentConstructor<BaseClassComponent>;
|
5
|
+
export type Extractor = <TComponent extends BaseCCConstructor>(this: TComponent & IClassComponentConstructor<InstanceType<TComponent>>, Component?: TComponent & IClassComponentConstructor<InstanceType<TComponent>>) => VoidFunctionComponent<InstanceType<TComponent>['props']>;
|
6
|
+
export {};
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.setFunctionName = void 0;
|
4
|
+
/** Provide more useful stack traces for otherwise non-specific function names. */
|
5
|
+
var setFunctionName = function (func, newName) {
|
6
|
+
try {
|
7
|
+
// Must use try block, as `name` is not configurable on older browsers, and may yield a TypeError.
|
8
|
+
Object.defineProperty(func, 'name', {
|
9
|
+
writable: true,
|
10
|
+
value: newName,
|
11
|
+
});
|
12
|
+
}
|
13
|
+
catch (error) {
|
14
|
+
console.warn(error);
|
15
|
+
}
|
16
|
+
};
|
17
|
+
exports.setFunctionName = setFunctionName;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const useRerender: () => () => void;
|
@@ -0,0 +1,11 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.useRerender = void 0;
|
4
|
+
var react_1 = require("react");
|
5
|
+
var useRerender = function () {
|
6
|
+
// Skip the value, we don't need it. Grab just the setter function.
|
7
|
+
var _a = (0, react_1.useState)(Date.now()), _forceRerender = _a[1];
|
8
|
+
var rerender = function () { return _forceRerender(Date.now()); };
|
9
|
+
return rerender;
|
10
|
+
};
|
11
|
+
exports.useRerender = useRerender;
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.Use = void 0;
|
4
|
+
var react_1 = require("react");
|
5
|
+
/**
|
6
|
+
* A component you can use to consume hooks
|
7
|
+
* in a {@link Component | React.Component} class component.
|
8
|
+
*/
|
9
|
+
var Use = function (params) {
|
10
|
+
var useGenericHook = params.hook, argumentsList = params.argumentsList, onUpdate = params.onUpdate;
|
11
|
+
var output = useGenericHook.apply(void 0, argumentsList);
|
12
|
+
(0, react_1.useEffect)(function () {
|
13
|
+
onUpdate(output);
|
14
|
+
}, [output]);
|
15
|
+
return null;
|
16
|
+
};
|
17
|
+
exports.Use = Use;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
interface HookWrapperProps<THookFunction extends AnyFunction> {
|
2
|
+
/**
|
3
|
+
* The React hook you which to consume.
|
4
|
+
* Render a separate instance of the `<Use />` component for each hook.
|
5
|
+
* You can also create a custom hook that combines multiple hooks,
|
6
|
+
* then use that wrapper hook with a single `<Use />` instance.
|
7
|
+
*/
|
8
|
+
hook: THookFunction;
|
9
|
+
/**
|
10
|
+
* An array containing the list of arguments
|
11
|
+
* to be passed to your hook, in the right order.
|
12
|
+
*/
|
13
|
+
argumentsList: Parameters<THookFunction>;
|
14
|
+
/**
|
15
|
+
* A callback that will be called with whatever value your hook returns.
|
16
|
+
* Use this to update your component's state with the value.
|
17
|
+
* This will allow your component to rerender whenever the hook returns a new value.
|
18
|
+
*/
|
19
|
+
onUpdate: (output: ReturnType<THookFunction>) => void;
|
20
|
+
}
|
21
|
+
export type ClassComponentHookWrapper = <Hook extends AnyFunction>(props: HookWrapperProps<Hook>) => null;
|
22
|
+
export {};
|
@@ -0,0 +1,94 @@
|
|
1
|
+
import type { TStateData } from '../../base';
|
2
|
+
import type { UseInstance } from './types/hook';
|
3
|
+
import type { CIBaseType, IComponentInstance } from './types/instance';
|
4
|
+
import type { IComponentInstanceClass } from './types/static';
|
5
|
+
import { ComponentLogic } from '../../classy/logic';
|
6
|
+
type AsyncAllowedEffectCallback = () => Awaitable<IVoidFunction>;
|
7
|
+
type o = object;
|
8
|
+
/** An empty function. It returns (void) without performing any operations. */
|
9
|
+
export declare const noOp: () => void;
|
10
|
+
/**
|
11
|
+
* A superset of {@link ComponentLogic} that adds support for lifecycle methods.
|
12
|
+
* This provides a declarative API for working with your React function component's lifecycle,
|
13
|
+
* a simpler alternative to the imperative approach with `useEffect` and/or `useMemo`.
|
14
|
+
*/
|
15
|
+
export declare class ComponentInstance<TProps extends o = {}, TState extends TStateData = WeakEmptyObject> extends ComponentLogic.Class<TProps, TState> {
|
16
|
+
/**
|
17
|
+
* Runs only _before_ first render, i.e before the component instance is mounted.
|
18
|
+
* Useful for logic that is involved in determining what to render.
|
19
|
+
*
|
20
|
+
* Updating local state from in here will abort the render cycle early, before changes are committed to the DOM,
|
21
|
+
* and prompt React to immediately rerender the component with the updated state value(s).
|
22
|
+
*
|
23
|
+
* Ignored on subsequent rerenders.
|
24
|
+
*/
|
25
|
+
beforeMount: IVoidFunction;
|
26
|
+
/**
|
27
|
+
* Runs only **_after_** first render, i.e after the component instance is mounted.
|
28
|
+
*
|
29
|
+
* Should usually only be used for logic that does not directly take part in determining what to render, like
|
30
|
+
* synchronize your component with some external system.
|
31
|
+
*
|
32
|
+
* Ignored on subsequent rerenders.
|
33
|
+
*
|
34
|
+
* Returns a cleanup function.
|
35
|
+
*/
|
36
|
+
onMount: AsyncAllowedEffectCallback;
|
37
|
+
private _templateContext;
|
38
|
+
get templateContext(): ReturnType<this["beforeRender"]>;
|
39
|
+
/**
|
40
|
+
* Runs _before_ every render cycle, including the first.
|
41
|
+
* Useful for logic that is involved in determining what to render.
|
42
|
+
*
|
43
|
+
* Updating local state from in here will abort the render cycle early, before changes are committed to the DOM,
|
44
|
+
* and prompt React to immediately rerender the component with the updated state value(s).
|
45
|
+
*/
|
46
|
+
beforeRender: () => object | void;
|
47
|
+
/**
|
48
|
+
* Runs **_after_** every render cycle, including the first.
|
49
|
+
*
|
50
|
+
* Should usually only be used for logic that does not directly take part in determining what to render, like
|
51
|
+
* synchronize your component with some external system.
|
52
|
+
*
|
53
|
+
* Returns a cleanup function.
|
54
|
+
*/
|
55
|
+
onRender: AsyncAllowedEffectCallback;
|
56
|
+
/**
|
57
|
+
* Runs when the component is unmounted.
|
58
|
+
* It is called _after_ the cleanup function returned by onMount.
|
59
|
+
*/
|
60
|
+
cleanUp: IVoidFunction;
|
61
|
+
}
|
62
|
+
export declare const useInstance: UseInstance;
|
63
|
+
export declare namespace ComponentInstance {
|
64
|
+
class Class<TProps extends object = {}, TState extends TStateData = WeakEmptyObject> extends ComponentInstance<TProps, TState> {
|
65
|
+
}
|
66
|
+
type Instance<Instance extends CIBaseType = Class> = IComponentInstance<Instance>;
|
67
|
+
type ClassType<Instance extends CIBaseType = Class> = IComponentInstanceClass<Instance>;
|
68
|
+
}
|
69
|
+
export {};
|
70
|
+
/** /
|
71
|
+
testing: {
|
72
|
+
class A extends ComponentInstance<{}, {}> {
|
73
|
+
static getInitialState: (p?: object) => ({putan: ''});
|
74
|
+
// k = this.props.o
|
75
|
+
a = this.state['_initialValues_'];
|
76
|
+
|
77
|
+
beforeRender = () => '';
|
78
|
+
|
79
|
+
useHooks = () => {
|
80
|
+
type a = typeof this._templateContext;
|
81
|
+
};
|
82
|
+
// hard empty has every key
|
83
|
+
// weak empty has no key
|
84
|
+
// weak empty is not assignable to hard empty
|
85
|
+
}
|
86
|
+
|
87
|
+
const a = useInstance(A, {o: ''});
|
88
|
+
a.a;
|
89
|
+
|
90
|
+
// a.props['o'];
|
91
|
+
type bbbb = A['state'];
|
92
|
+
type ttt = bbbb['put'];
|
93
|
+
}
|
94
|
+
/**/
|