@cleanweb/oore 2.0.0-alpha.16 → 2.0.0-alpha.18
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/build/_cjs/base/index.d.ts +3 -0
- package/build/_cjs/base/index.js +19 -0
- package/build/_cjs/base/merged-state.d.ts +20 -0
- package/build/_cjs/base/merged-state.js +61 -0
- package/build/_cjs/base/methods.d.ts +58 -0
- package/build/_cjs/base/methods.js +95 -0
- package/build/_cjs/base/state/class-types.d.ts +20 -0
- package/build/_cjs/base/state/class-types.js +2 -0
- package/build/_cjs/base/state/class.d.ts +69 -0
- package/build/_cjs/base/state/class.js +129 -0
- package/build/_cjs/base/state/hook-types.d.ts +32 -0
- package/build/_cjs/base/state/hook-types.js +2 -0
- package/build/_cjs/base/state/hooks.d.ts +12 -0
- package/build/_cjs/base/state/hooks.js +41 -0
- package/build/_cjs/base/state/index.d.ts +9 -0
- package/build/_cjs/base/state/index.js +35 -0
- package/build/_cjs/classy/class/index.d.ts +128 -0
- package/build/_cjs/classy/class/index.js +174 -0
- package/build/_cjs/classy/class/types/extractor.d.ts +5 -0
- package/build/_cjs/classy/class/types/extractor.js +2 -0
- package/build/_cjs/classy/class/utils/function-name.d.ts +2 -0
- package/build/_cjs/classy/class/utils/function-name.js +17 -0
- package/build/_cjs/classy/index.d.ts +3 -0
- package/build/_cjs/classy/index.js +19 -0
- package/build/_cjs/classy/instance/index.d.ts +144 -0
- package/build/_cjs/classy/instance/index.js +177 -0
- package/build/_cjs/classy/instance/mount-callbacks.d.ts +5 -0
- package/build/_cjs/classy/instance/mount-callbacks.js +30 -0
- package/build/_cjs/classy/instance/types/hook.d.ts +13 -0
- package/build/_cjs/classy/instance/types/hook.js +2 -0
- package/build/_cjs/classy/logic/index.d.ts +116 -0
- package/build/_cjs/classy/logic/index.js +123 -0
- package/build/_cjs/classy/logic/types/hook.d.ts +16 -0
- package/build/_cjs/classy/logic/types/hook.js +2 -0
- package/build/_cjs/docs-src/api/base-classes.d.ts +3 -0
- package/build/_cjs/docs-src/api/base-classes.js +9 -0
- package/build/_cjs/docs-src/api/index.d.ts +13 -0
- package/build/_cjs/docs-src/api/index.js +44 -0
- package/build/_cjs/docs-src/api/references.d.ts +5 -0
- package/build/_cjs/docs-src/api/references.js +31 -0
- package/build/_cjs/helpers/errors.d.ts +10 -0
- package/build/_cjs/helpers/errors.js +21 -0
- package/build/_cjs/helpers/index.d.ts +13 -0
- package/build/_cjs/helpers/index.js +31 -0
- package/build/_cjs/helpers/mount-state.d.ts +5 -0
- package/build/_cjs/helpers/mount-state.js +25 -0
- package/build/_cjs/helpers/rerender.d.ts +24 -0
- package/build/_cjs/helpers/rerender.js +42 -0
- package/build/_cjs/helpers/type-guards.d.ts +1 -0
- package/build/_cjs/helpers/type-guards.js +8 -0
- package/build/_cjs/helpers/use-component/index.d.ts +6 -0
- package/build/_cjs/helpers/use-component/index.js +17 -0
- package/build/_cjs/helpers/use-component/types.d.ts +22 -0
- package/build/_cjs/helpers/use-component/types.js +2 -0
- package/build/_cjs/index.d.ts +3 -0
- package/build/_cjs/index.js +19 -0
- package/build/_cjs/slots/hook.d.ts +20 -0
- package/build/_cjs/slots/hook.js +143 -0
- package/build/_cjs/slots/index.d.ts +1 -0
- package/build/_cjs/slots/index.js +17 -0
- package/build/_cjs/slots/types.d.ts +131 -0
- package/build/_cjs/slots/types.js +2 -0
- package/build/base/index.js +19 -3
- package/build/base/merged-state.js +35 -54
- package/build/base/methods.js +23 -25
- package/build/base/state/class-types.js +2 -1
- package/build/base/state/class.js +49 -69
- package/build/base/state/hook-types.js +2 -1
- package/build/base/state/hooks.js +12 -12
- package/build/base/state/index.js +32 -4
- package/build/classy/class/index.js +89 -109
- package/build/classy/class/types/extractor.js +2 -1
- package/build/classy/class/utils/function-name.js +5 -1
- package/build/classy/index.js +19 -3
- package/build/classy/instance/index.js +62 -84
- package/build/classy/instance/mount-callbacks.js +12 -8
- package/build/classy/instance/types/hook.js +2 -1
- package/build/classy/logic/index.js +27 -28
- package/build/classy/logic/types/hook.js +2 -1
- package/build/docs-src/api/base-classes.js +9 -3
- package/build/docs-src/api/index.js +39 -8
- package/build/docs-src/api/references.js +31 -5
- package/build/globals.d.ts +130 -83
- package/build/helpers/errors.js +5 -1
- package/build/helpers/index.js +23 -5
- package/build/helpers/mount-state.js +10 -6
- package/build/helpers/rerender.js +16 -12
- package/build/helpers/type-guards.js +6 -2
- package/build/helpers/use-component/index.js +9 -5
- package/build/helpers/use-component/types.js +2 -1
- package/build/index.d.ts +0 -1
- package/build/index.js +19 -3
- package/build/slots/hook.js +58 -36
- package/build/slots/index.js +17 -1
- package/build/slots/types.js +2 -1
- package/build/tsconfig.json +5 -6
- package/package.json +31 -12
- package/build/globals.js +0 -3
|
@@ -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,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./classy"), exports);
|
|
18
|
+
__exportStar(require("./base"), exports);
|
|
19
|
+
__exportStar(require("./helpers"), exports);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode, ReactPortal } from 'react';
|
|
2
|
+
import type { IUseSlots, PotentialSlotComponent } from './types';
|
|
3
|
+
export declare const isElementChild: (child: ReactNode) => child is ReactElement<any, any>;
|
|
4
|
+
interface IGetSlotName {
|
|
5
|
+
(TargetComponent: PotentialSlotComponent, child?: ReactElement): string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare const getComponentSlotName: IGetSlotName;
|
|
8
|
+
export declare const isPortalChild: (child: ReactNode) => child is ReactPortal;
|
|
9
|
+
/**
|
|
10
|
+
* Groups `children` prop into predefined slots.
|
|
11
|
+
*
|
|
12
|
+
* @returns A {@link TUseSlotsResult} array,
|
|
13
|
+
* which includes a `slotNodes` object that maps the keys from
|
|
14
|
+
* the predefined {@link Caller.slots} object to the corresponding
|
|
15
|
+
* React node(s) that were rendered for that slot.
|
|
16
|
+
*
|
|
17
|
+
* @see {@link SlotComponent} for more on how to use the returned slot nodes.
|
|
18
|
+
*/
|
|
19
|
+
export declare const useSlots: IUseSlots;
|
|
20
|
+
export type { SlottedComponent, TSlotsRecord, SlotComponent, PotentialSlotComponent, } from './types';
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.useSlots = exports.isPortalChild = exports.getComponentSlotName = exports.isElementChild = void 0;
|
|
27
|
+
const errors_1 = require("../helpers/errors");
|
|
28
|
+
const react_1 = __importStar(require("react"));
|
|
29
|
+
const isElementChild = (child) => {
|
|
30
|
+
if (child && typeof child === 'object' && 'type' in child) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
};
|
|
35
|
+
exports.isElementChild = isElementChild;
|
|
36
|
+
const getComponentSlotName = (TargetComponent, child) => {
|
|
37
|
+
if (child) {
|
|
38
|
+
const keyTypes = ['string', 'number', 'symbol'];
|
|
39
|
+
const slotName = child.props['data-slot-name'];
|
|
40
|
+
if (keyTypes.includes(typeof slotName)) {
|
|
41
|
+
return slotName;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (typeof TargetComponent === 'string') {
|
|
45
|
+
return TargetComponent;
|
|
46
|
+
}
|
|
47
|
+
else if ('slotName' in TargetComponent) {
|
|
48
|
+
return TargetComponent.slotName;
|
|
49
|
+
}
|
|
50
|
+
else if ('displayName' in TargetComponent) {
|
|
51
|
+
return TargetComponent.displayName;
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
};
|
|
55
|
+
exports.getComponentSlotName = getComponentSlotName;
|
|
56
|
+
const isPortalChild = (child) => {
|
|
57
|
+
return (!!child
|
|
58
|
+
&& typeof child === 'object'
|
|
59
|
+
&& 'children' in child);
|
|
60
|
+
};
|
|
61
|
+
exports.isPortalChild = isPortalChild;
|
|
62
|
+
/**
|
|
63
|
+
* Groups `children` prop into predefined slots.
|
|
64
|
+
*
|
|
65
|
+
* @returns A {@link TUseSlotsResult} array,
|
|
66
|
+
* which includes a `slotNodes` object that maps the keys from
|
|
67
|
+
* the predefined {@link Caller.slots} object to the corresponding
|
|
68
|
+
* React node(s) that were rendered for that slot.
|
|
69
|
+
*
|
|
70
|
+
* @see {@link SlotComponent} for more on how to use the returned slot nodes.
|
|
71
|
+
*/
|
|
72
|
+
const useSlots = (children, Caller) => {
|
|
73
|
+
const slotsAliasLookup = (0, react_1.useMemo)(() => {
|
|
74
|
+
const entries = Object.entries(Caller.Slots);
|
|
75
|
+
const aliasLookup = {};
|
|
76
|
+
entries.forEach(([alias, RegisteredSlotComponent]) => {
|
|
77
|
+
const slotName = (0, exports.getComponentSlotName)(RegisteredSlotComponent);
|
|
78
|
+
if (!slotName) {
|
|
79
|
+
(0, errors_1.throwDevError)(`A registered slot component did not have a slot name. All components registered as slots must either be a string tag-name or a React component with either "slotName" or "displayName". The affected component was: ${RegisteredSlotComponent}`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
aliasLookup[slotName] = alias;
|
|
83
|
+
});
|
|
84
|
+
return aliasLookup;
|
|
85
|
+
}, [Caller.Slots]);
|
|
86
|
+
// @todo Expose original source order of `children` with respect to slot aliases.
|
|
87
|
+
const result = (0, react_1.useMemo)(() => {
|
|
88
|
+
var _a;
|
|
89
|
+
const slotNodes = {};
|
|
90
|
+
const unmatchedChildren = [];
|
|
91
|
+
const invalidChildren = [];
|
|
92
|
+
const requiredSlotAliases = [
|
|
93
|
+
...((_a = Caller.requiredSlotAliases) !== null && _a !== void 0 ? _a : [])
|
|
94
|
+
];
|
|
95
|
+
react_1.default.Children.forEach(children, (_child) => {
|
|
96
|
+
var _a;
|
|
97
|
+
const child = _child;
|
|
98
|
+
if (!child) {
|
|
99
|
+
invalidChildren.push(child);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (!react_1.default.isValidElement(child)) {
|
|
103
|
+
console.warn(`Invalid node found in JSX children while parsing slots. Got: "${child}".`);
|
|
104
|
+
invalidChildren.push(child);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
;
|
|
108
|
+
// @todo Check for fragment
|
|
109
|
+
if (!(0, exports.isElementChild)(child)) {
|
|
110
|
+
unmatchedChildren.push(child);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const slotAlias = (() => {
|
|
114
|
+
var _a;
|
|
115
|
+
const slotName = (0, exports.getComponentSlotName)(child.type, child);
|
|
116
|
+
return slotName ? (_a = slotsAliasLookup[slotName]) !== null && _a !== void 0 ? _a : null : null;
|
|
117
|
+
})();
|
|
118
|
+
if (slotAlias) {
|
|
119
|
+
if (typeof Caller.Slots[slotAlias] !== 'string') {
|
|
120
|
+
if ((_a = Caller.Slots[slotAlias]) === null || _a === void 0 ? void 0 : _a.isRequiredSlot) {
|
|
121
|
+
requiredSlotAliases.push(slotAlias);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (slotNodes[slotAlias]) {
|
|
125
|
+
slotNodes[slotAlias].push(child);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
slotNodes[slotAlias] = [child];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else
|
|
132
|
+
unmatchedChildren.push(child);
|
|
133
|
+
});
|
|
134
|
+
requiredSlotAliases.forEach((slotAlias) => {
|
|
135
|
+
if (!slotNodes[slotAlias]) {
|
|
136
|
+
(0, errors_1.throwDevError)(`Missing required slot "${String(slotAlias)}".`);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
return [slotNodes, unmatchedChildren, invalidChildren];
|
|
140
|
+
}, [children]);
|
|
141
|
+
return result;
|
|
142
|
+
};
|
|
143
|
+
exports.useSlots = useSlots;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './hook';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./hook"), exports);
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode, ComponentType, ReactPortal, JSX } from 'react';
|
|
2
|
+
/** @todo ComponentType force children to be ReactNode, but custom components can have any children type. */
|
|
3
|
+
type JSXTagLike = string | keyof JSX.IntrinsicElements | ComponentType<any>;
|
|
4
|
+
/** This fixes overly narrow T type used by React's ComponentProps type. */
|
|
5
|
+
export type ComponentProps<T extends JSXTagLike> = (T extends ComponentType<infer P> ? P : T extends keyof JSX.IntrinsicElements ? JSX.IntrinsicElements[T] : {});
|
|
6
|
+
export type TSlotName = keyof any;
|
|
7
|
+
export type TSlotAlias = keyof any;
|
|
8
|
+
/**
|
|
9
|
+
* A map of slot aliases to actual {@link SlotComponent}s.
|
|
10
|
+
*
|
|
11
|
+
* The `useSlots` hook will create a corresponding key for
|
|
12
|
+
* each alias in this record to hold any `ReactNode`s rendered for that slot.
|
|
13
|
+
*/
|
|
14
|
+
export type TSlotsRecord<TKey extends TSlotAlias = TSlotAlias> = {
|
|
15
|
+
[Key in TKey]: SlotComponent<string | ComponentType<any>>;
|
|
16
|
+
};
|
|
17
|
+
export type DisplayNamedComponent<TComponent extends ComponentType<any> = ComponentType<any>, TName extends string = string> = TComponent & {
|
|
18
|
+
displayName: TName;
|
|
19
|
+
};
|
|
20
|
+
interface ISlotConfig<TName> {
|
|
21
|
+
slotName: TName;
|
|
22
|
+
/**
|
|
23
|
+
* @deprecated The SlottedComponent should be responsible for indicating which slots it requires.
|
|
24
|
+
* Individual slot components may be reused by multiple slotted components with varying requirements.
|
|
25
|
+
*/
|
|
26
|
+
isRequiredSlot?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A child component used to insert content into a specific slot in the parent component.
|
|
30
|
+
* This can either be a string, or a React component with a `slotName` property.
|
|
31
|
+
*
|
|
32
|
+
* > `displayName` is no longer supported as a fallback for `slotName`.
|
|
33
|
+
*
|
|
34
|
+
* ### Strings
|
|
35
|
+
* For strings, they are treated by React a native tags. This lets you use custom strings
|
|
36
|
+
* as if you are rendering a custom Web Component, or simply handle specific HTML tags in a specific way.
|
|
37
|
+
*
|
|
38
|
+
* If using a custom string, you will want to handle it in the parent component by simply forwarding the slot's
|
|
39
|
+
* props to an actual element of your choice.
|
|
40
|
+
*
|
|
41
|
+
* So consumers may pass the following as `children`.
|
|
42
|
+
* ```jsx
|
|
43
|
+
* <option-slot>Click</option-slot>
|
|
44
|
+
* ```
|
|
45
|
+
* and you can map that to
|
|
46
|
+
* ```jsx
|
|
47
|
+
* <button
|
|
48
|
+
* {...slotNodes.Option[0].props}
|
|
49
|
+
* type="button"
|
|
50
|
+
* />
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* ### React Components
|
|
54
|
+
* For slot components that are actual React components, the parent can simply
|
|
55
|
+
* render the slot node directly.
|
|
56
|
+
*
|
|
57
|
+
* So consumers may pass the following as `children`.
|
|
58
|
+
* ```jsx
|
|
59
|
+
* <Parent.Slots.Content>
|
|
60
|
+
* Some awesome content.
|
|
61
|
+
* </Parent.Slots.Content>
|
|
62
|
+
* ```
|
|
63
|
+
* and you can map that to
|
|
64
|
+
* ```jsx
|
|
65
|
+
* return <>
|
|
66
|
+
* <h1>Title</h1>
|
|
67
|
+
* {slotNodes.Content}
|
|
68
|
+
* <footer>Powered by oore</footer>
|
|
69
|
+
* </>
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* This means `Parent.Slots.Content` must be defined as a proper React component
|
|
73
|
+
* and is solely responsible for doing something with the `"Some awesome content."`
|
|
74
|
+
* which was passed into it as children.
|
|
75
|
+
*
|
|
76
|
+
* This is unlike the string version where the parent component
|
|
77
|
+
* extracts the props passed to the slot and handles
|
|
78
|
+
* what the slot actually renders.
|
|
79
|
+
*/
|
|
80
|
+
export type SlotComponent<TComponent extends JSXTagLike = ComponentType<any>, TName extends TSlotName = TSlotName> = (TComponent extends string ? TComponent : TComponent & ISlotConfig<TName>);
|
|
81
|
+
/**
|
|
82
|
+
* A parent component which accepts content that can be grouped into predefined slots.
|
|
83
|
+
* By convention, it should have a `slots` property which is a {@link TSlotsRecord}.
|
|
84
|
+
*
|
|
85
|
+
* This allows consumers access the predefined slot components
|
|
86
|
+
* directly from the parent component itself,
|
|
87
|
+
* through an alias that is easy to remember.
|
|
88
|
+
*/
|
|
89
|
+
export type SlottedComponent<TOwner extends object = ComponentType<any>, TSlots extends TSlotsRecord = TSlotsRecord> = TOwner & {
|
|
90
|
+
Slots: TSlots;
|
|
91
|
+
requiredSlotAliases?: Array<keyof TSlots>;
|
|
92
|
+
};
|
|
93
|
+
export type TypedNode<P, T extends JSXTagLike> = (ReactElement<P, T> | (ReactElement<P, T> & ReactPortal));
|
|
94
|
+
export type TSlotNode<TSlotted extends SlottedComponent, Key extends keyof TSlotted['Slots'] = keyof TSlotted['Slots']> = (TypedNode<ComponentProps<TSlotted['Slots'][Key]>, TSlotted['Slots'][Key]>);
|
|
95
|
+
/**
|
|
96
|
+
* A record of slot aliases mapped to the corresponding `ReactNode`(s)
|
|
97
|
+
* to be rendered for that slot.
|
|
98
|
+
*/
|
|
99
|
+
export type TSlotNodes<TSlotted extends SlottedComponent> = {
|
|
100
|
+
[Key in keyof TSlotted['Slots']]?: Array<TSlotNode<TSlotted, Key>>;
|
|
101
|
+
};
|
|
102
|
+
export type TUseSlotsResult<TSlotted extends SlottedComponent> = Readonly<[
|
|
103
|
+
/**
|
|
104
|
+
* A record of slot aliases to their corresponding React nodes.
|
|
105
|
+
* Each alias maps to an array of one or more React nodes that were passed
|
|
106
|
+
* as children for that slot.
|
|
107
|
+
*
|
|
108
|
+
* If a slot was not rendered in `children`, it's alias will be `undefined` in this object.
|
|
109
|
+
*/
|
|
110
|
+
slotNodes: TSlotNodes<TSlotted>,
|
|
111
|
+
/**
|
|
112
|
+
* Valid React nodes passed as children which did not match any of the
|
|
113
|
+
* predefined slots.
|
|
114
|
+
*/
|
|
115
|
+
unmatchedChildren: ReactNode[],
|
|
116
|
+
/**
|
|
117
|
+
* Items included in `children` which are not valid React nodes.
|
|
118
|
+
*/
|
|
119
|
+
invalidChildren: any[]
|
|
120
|
+
]>;
|
|
121
|
+
export interface IUseSlots {
|
|
122
|
+
<TSlotted extends SlottedComponent>(
|
|
123
|
+
/**
|
|
124
|
+
* Your component's `children` prop.
|
|
125
|
+
* The nodes it contains will be categorized and
|
|
126
|
+
* grouped according to the predefined {@link slotComponents}.
|
|
127
|
+
*/
|
|
128
|
+
children: ReactNode, Caller: TSlotted): TUseSlotsResult<TSlotted>;
|
|
129
|
+
}
|
|
130
|
+
export type PotentialSlotComponent = string | SlotComponent | ComponentType<any>;
|
|
131
|
+
export {};
|
package/build/base/index.js
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./state"), exports);
|
|
18
|
+
__exportStar(require("./methods"), exports);
|
|
19
|
+
__exportStar(require("./merged-state"), exports);
|
|
@@ -1,80 +1,61 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useMergedState = void 0;
|
|
4
|
+
require("../globals");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
class MergedState {
|
|
7
|
+
static useRefresh() {
|
|
8
|
+
[this._values_, this.setState] = (0, react_1.useState)(this.initialState);
|
|
9
|
+
}
|
|
10
|
+
get put() {
|
|
11
|
+
return Object.assign({}, this._setters_);
|
|
12
|
+
}
|
|
13
|
+
get initialState() {
|
|
14
|
+
return Object.assign({}, this._initialValues_);
|
|
15
|
+
}
|
|
16
|
+
constructor(initialState) {
|
|
17
17
|
this._initialValues_ = {};
|
|
18
18
|
this._values_ = {};
|
|
19
19
|
this._setters_ = {};
|
|
20
|
-
this.putMany =
|
|
21
|
-
|
|
20
|
+
this.putMany = (newValues) => {
|
|
21
|
+
this.setState(Object.assign(Object.assign({}, this._values_), newValues));
|
|
22
22
|
};
|
|
23
23
|
this.reservedKeys = Object.keys(this);
|
|
24
24
|
this.valueKeys = [];
|
|
25
|
-
this._initialValues_ =
|
|
26
|
-
this._values_ =
|
|
27
|
-
Object.keys(initialState).forEach(
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
throw new Error(
|
|
25
|
+
this._initialValues_ = Object.assign({}, initialState);
|
|
26
|
+
this._values_ = Object.assign({}, initialState);
|
|
27
|
+
Object.keys(initialState).forEach((_key) => {
|
|
28
|
+
const key = _key;
|
|
29
|
+
if (this.reservedKeys.includes(key)) {
|
|
30
|
+
throw new Error(`The name "${key}" is reserved by CleanState and cannot be used to index state variables. Please use a different key.`);
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
var _a;
|
|
32
|
+
this.valueKeys.push(key);
|
|
33
|
+
this._setters_[key] = (value) => {
|
|
35
34
|
// this._values_[key] = value;
|
|
36
|
-
|
|
35
|
+
this.setState(Object.assign(Object.assign({}, this._values_), { [key]: value }));
|
|
37
36
|
};
|
|
38
|
-
|
|
39
|
-
Object.defineProperty(
|
|
40
|
-
get
|
|
37
|
+
const self = this;
|
|
38
|
+
Object.defineProperty(this, key, {
|
|
39
|
+
get() {
|
|
41
40
|
return self._values_[key];
|
|
42
41
|
},
|
|
43
|
-
set
|
|
42
|
+
set(value) {
|
|
44
43
|
self._setters_[key](value);
|
|
45
44
|
},
|
|
46
45
|
enumerable: true,
|
|
47
46
|
});
|
|
48
47
|
});
|
|
49
48
|
}
|
|
50
|
-
|
|
51
|
-
var _a;
|
|
52
|
-
_a = useState(this.initialState), this._values_ = _a[0], this.setState = _a[1];
|
|
53
|
-
};
|
|
54
|
-
Object.defineProperty(MergedState.prototype, "put", {
|
|
55
|
-
get: function () {
|
|
56
|
-
return __assign({}, this._setters_);
|
|
57
|
-
},
|
|
58
|
-
enumerable: false,
|
|
59
|
-
configurable: true
|
|
60
|
-
});
|
|
61
|
-
Object.defineProperty(MergedState.prototype, "initialState", {
|
|
62
|
-
get: function () {
|
|
63
|
-
return __assign({}, this._initialValues_);
|
|
64
|
-
},
|
|
65
|
-
enumerable: false,
|
|
66
|
-
configurable: true
|
|
67
|
-
});
|
|
68
|
-
return MergedState;
|
|
69
|
-
}());
|
|
49
|
+
}
|
|
70
50
|
/**
|
|
71
51
|
* Similar to {@link useCleanState},
|
|
72
52
|
* but uses a single `useState` call for the entire state object.
|
|
73
53
|
*/
|
|
74
|
-
|
|
75
|
-
|
|
54
|
+
const useMergedState = (initialState) => {
|
|
55
|
+
const cleanState = (0, react_1.useRef)((0, react_1.useMemo)(() => {
|
|
76
56
|
return new MergedState(initialState);
|
|
77
57
|
}, [])).current;
|
|
78
58
|
MergedState.useRefresh.call(cleanState);
|
|
79
59
|
return cleanState;
|
|
80
60
|
};
|
|
61
|
+
exports.useMergedState = useMergedState;
|
package/build/base/methods.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* @module ComponentMethods
|
|
3
4
|
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useMethods = exports.ComponentMethods = void 0;
|
|
4
7
|
// Values
|
|
5
|
-
|
|
8
|
+
const react_1 = require("react");
|
|
6
9
|
/**
|
|
7
10
|
* @summary
|
|
8
11
|
* Base class for a class that holds methods for a function component.
|
|
@@ -13,8 +16,8 @@ import { useMemo, useRef } from 'react';
|
|
|
13
16
|
*
|
|
14
17
|
* Call the {@link useMethods} hook inside your function component to instantiate the class.
|
|
15
18
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
class ComponentMethods {
|
|
20
|
+
constructor() {
|
|
18
21
|
/**
|
|
19
22
|
* Persist class members during HMR. {@include ../classy/logic/hrm-preserve-keys.md}
|
|
20
23
|
* @privateRemarks
|
|
@@ -22,9 +25,8 @@ var ComponentMethods = /** @class */ (function () {
|
|
|
22
25
|
*/
|
|
23
26
|
this._hmrPreserveKeys = []; // @todo Keep undefined. Update to empty array after instantiation in dev env.
|
|
24
27
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
export { ComponentMethods };
|
|
28
|
+
}
|
|
29
|
+
exports.ComponentMethods = ComponentMethods;
|
|
28
30
|
;
|
|
29
31
|
/**
|
|
30
32
|
* Returns an instance of the provided class,
|
|
@@ -32,13 +34,9 @@ export { ComponentMethods };
|
|
|
32
34
|
*
|
|
33
35
|
* `state` should be an instance of `CleanState` created with {@link useCleanState}.
|
|
34
36
|
*/
|
|
35
|
-
|
|
37
|
+
const useMethods = (...args) => {
|
|
36
38
|
var _a;
|
|
37
|
-
|
|
38
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
39
|
-
args[_i] = arguments[_i];
|
|
40
|
-
}
|
|
41
|
-
var Methods = args[0], _b = args[1], props = _b === void 0 ? {} : _b, state = args[2];
|
|
39
|
+
const [Methods, props = {}, state] = args;
|
|
42
40
|
// Vite HMR seems to sometimes reinitialize useMemo calls after a hot update,
|
|
43
41
|
// causing the instance to be unexpectedly recreated in the middle of the component's lifecycle.
|
|
44
42
|
// But useRef and useState values appear to always be preserved whenever this happens.
|
|
@@ -46,9 +44,9 @@ var useMethods = function () {
|
|
|
46
44
|
// In production, we only use the latestInstance the first time, and it's ignored every other time.
|
|
47
45
|
// This means changing the class at runtime will have no effect in production.
|
|
48
46
|
// latestInstance is only extracted into a separate variable for use in dev mode during HMR.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
const latestInstance = (0, react_1.useMemo)(() => new Methods(), [Methods]);
|
|
48
|
+
const instanceRef = (0, react_1.useRef)(latestInstance);
|
|
49
|
+
const refreshState = () => {
|
|
52
50
|
// @ts-expect-error
|
|
53
51
|
instanceRef.current.props = props;
|
|
54
52
|
// @ts-expect-error
|
|
@@ -56,29 +54,29 @@ var useMethods = function () {
|
|
|
56
54
|
instanceRef.current.state = state;
|
|
57
55
|
};
|
|
58
56
|
if (process.env.NODE_ENV === 'development' && instanceRef.current !== latestInstance) {
|
|
59
|
-
|
|
60
|
-
latestInstance._hmrPreserveKeys.forEach(
|
|
61
|
-
|
|
57
|
+
const oldInstance = instanceRef.current;
|
|
58
|
+
latestInstance._hmrPreserveKeys.forEach((_key) => {
|
|
59
|
+
const key = _key;
|
|
62
60
|
// @ts-expect-error We're assigning to readonly properties. Also, Typescript doesn't know that the type of the left and right side will always match, due to the dynamic access.
|
|
63
|
-
latestInstance[key] =
|
|
61
|
+
latestInstance[key] = oldInstance[key];
|
|
64
62
|
});
|
|
65
63
|
// Ensure that any stale references to oldInstance within the app
|
|
66
64
|
// will end up retrieving up-to-date values from latestInstance
|
|
67
65
|
// through the prototype chain.
|
|
68
|
-
Reflect.ownKeys(
|
|
69
|
-
|
|
70
|
-
delete
|
|
66
|
+
Reflect.ownKeys(oldInstance).forEach((_key) => {
|
|
67
|
+
const key = _key;
|
|
68
|
+
delete oldInstance[key];
|
|
71
69
|
});
|
|
72
|
-
Object.setPrototypeOf(
|
|
70
|
+
Object.setPrototypeOf(oldInstance, latestInstance);
|
|
73
71
|
instanceRef.current = latestInstance;
|
|
74
72
|
refreshState();
|
|
75
|
-
(_a = latestInstance._onHmrUpdate) === null || _a === void 0 ? void 0 : _a.call(latestInstance,
|
|
73
|
+
(_a = latestInstance._onHmrUpdate) === null || _a === void 0 ? void 0 : _a.call(latestInstance, oldInstance);
|
|
76
74
|
}
|
|
77
75
|
else
|
|
78
76
|
refreshState();
|
|
79
77
|
return instanceRef.current;
|
|
80
78
|
};
|
|
81
|
-
|
|
79
|
+
exports.useMethods = useMethods;
|
|
82
80
|
/** /type_testing: {
|
|
83
81
|
let a = async () => {
|
|
84
82
|
const a: object = {b: ''};
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|