@cleanweb/oore 1.1.0 → 1.2.0-alpha.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/build/helpers/errors.d.ts +10 -0
- package/build/helpers/errors.js +21 -0
- package/build/slots/hook.d.ts +6 -0
- package/build/slots/hook.js +83 -0
- package/build/slots/index.d.ts +1 -0
- package/build/slots/index.js +17 -0
- package/build/slots/types.d.ts +31 -0
- package/build/slots/types.js +4 -0
- package/package.json +2 -6
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Throw an error with the provided message
|
|
3
|
+
* only when `NODE_ENV` is *not* 'production'.
|
|
4
|
+
*
|
|
5
|
+
* In production, this falls back to just a console warning.
|
|
6
|
+
*
|
|
7
|
+
* Useful for enforcing certain conditions in development
|
|
8
|
+
* while failing more gracefully in production.
|
|
9
|
+
*/
|
|
10
|
+
export declare const throwDevError: (message: string) => void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.throwDevError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Throw an error with the provided message
|
|
6
|
+
* only when `NODE_ENV` is *not* 'production'.
|
|
7
|
+
*
|
|
8
|
+
* In production, this falls back to just a console warning.
|
|
9
|
+
*
|
|
10
|
+
* Useful for enforcing certain conditions in development
|
|
11
|
+
* while failing more gracefully in production.
|
|
12
|
+
*/
|
|
13
|
+
var throwDevError = function (message) {
|
|
14
|
+
if (process.env.NODE_ENV === 'production') {
|
|
15
|
+
console.warn(message);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
throw new Error(message);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
exports.throwDevError = throwDevError;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
import type { IUseSlots, PotentialSlotComponent } from './types';
|
|
3
|
+
export declare const isElementChild: (child: ReactNode) => child is ReactElement<any, any>;
|
|
4
|
+
export declare const getComponentSlotName: (TargetComponent: PotentialSlotComponent) => string | number | symbol | undefined;
|
|
5
|
+
export declare const useSlots: IUseSlots;
|
|
6
|
+
export type { SlotNamedComponent, SlottedComponent, TSlotsRecord, PotentialSlotComponent, } from './types';
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useSlots = exports.getComponentSlotName = exports.isElementChild = void 0;
|
|
7
|
+
var errors_1 = require("../helpers/errors");
|
|
8
|
+
var react_1 = __importDefault(require("react"));
|
|
9
|
+
var isElementChild = function (child) {
|
|
10
|
+
if (child && typeof child === 'object' && 'type' in child) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
};
|
|
15
|
+
exports.isElementChild = isElementChild;
|
|
16
|
+
var getComponentSlotName = function (TargetComponent) {
|
|
17
|
+
if (typeof TargetComponent === 'string') {
|
|
18
|
+
return TargetComponent;
|
|
19
|
+
}
|
|
20
|
+
else if ('slotName' in TargetComponent) {
|
|
21
|
+
return TargetComponent.slotName;
|
|
22
|
+
}
|
|
23
|
+
else if ('displayName' in TargetComponent) {
|
|
24
|
+
return TargetComponent.displayName;
|
|
25
|
+
}
|
|
26
|
+
else
|
|
27
|
+
return undefined;
|
|
28
|
+
};
|
|
29
|
+
exports.getComponentSlotName = getComponentSlotName;
|
|
30
|
+
var useSlots = function (children, slotComponents) {
|
|
31
|
+
var useMemo = react_1.default.useMemo;
|
|
32
|
+
console.log({ slotComponents: slotComponents });
|
|
33
|
+
var slotsAliasLookup = useMemo(function () {
|
|
34
|
+
var entries = Object.entries(slotComponents);
|
|
35
|
+
var aliasLookup = {};
|
|
36
|
+
entries.forEach(function (_a) {
|
|
37
|
+
var alias = _a[0], RegisteredSlotComponent = _a[1];
|
|
38
|
+
var slotName = (0, exports.getComponentSlotName)(RegisteredSlotComponent);
|
|
39
|
+
if (!slotName) {
|
|
40
|
+
(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: ".concat(RegisteredSlotComponent));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
return aliasLookup[slotName] = alias;
|
|
44
|
+
});
|
|
45
|
+
return aliasLookup;
|
|
46
|
+
}, [slotComponents]);
|
|
47
|
+
console.log({ slotsAliasLookup: slotsAliasLookup });
|
|
48
|
+
var result = useMemo(function () {
|
|
49
|
+
var slotNodes = {};
|
|
50
|
+
var unmatchedChildren = [];
|
|
51
|
+
var invalidChildren = [];
|
|
52
|
+
react_1.default.Children.forEach(children, function (child) {
|
|
53
|
+
if (!child) {
|
|
54
|
+
invalidChildren.push(child);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (!react_1.default.isValidElement(child)) {
|
|
58
|
+
console.warn("Invalid node found in JSX children while parsing slots. Got: \"".concat(child, "\"."));
|
|
59
|
+
invalidChildren.push(child);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
;
|
|
63
|
+
if (!(0, exports.isElementChild)(child)) {
|
|
64
|
+
unmatchedChildren.push(child);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
var slotAlias = (function () {
|
|
68
|
+
var ChildComponent = child.type;
|
|
69
|
+
var slotName = (0, exports.getComponentSlotName)(ChildComponent);
|
|
70
|
+
return slotName ? slotsAliasLookup[slotName] : null;
|
|
71
|
+
})();
|
|
72
|
+
console.log('match:', { key: slotAlias });
|
|
73
|
+
if (slotAlias)
|
|
74
|
+
slotNodes[slotAlias] = child;
|
|
75
|
+
else
|
|
76
|
+
unmatchedChildren.push(child);
|
|
77
|
+
});
|
|
78
|
+
console.log({ unmatchedChildren: unmatchedChildren, invalidChildren: invalidChildren });
|
|
79
|
+
return [slotNodes, unmatchedChildren, invalidChildren];
|
|
80
|
+
}, [children]);
|
|
81
|
+
return result;
|
|
82
|
+
};
|
|
83
|
+
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,31 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode, JSXElementConstructor, FunctionComponent } from 'react';
|
|
2
|
+
export type TComponent = JSXElementConstructor<any>;
|
|
3
|
+
export type TSlotName = keyof any;
|
|
4
|
+
export type TSlotAlias = keyof any;
|
|
5
|
+
export type TSlotsRecord<TKey extends TSlotAlias = TSlotAlias> = {
|
|
6
|
+
[Key in TKey]: (string | SlotComponent);
|
|
7
|
+
};
|
|
8
|
+
export interface DisplayNamedComponent<TProps extends any = any> extends FunctionComponent<TProps> {
|
|
9
|
+
displayName: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SlotNamedComponent<TProps extends any = any> {
|
|
12
|
+
(props: TProps): ReactNode;
|
|
13
|
+
slotName: TSlotName;
|
|
14
|
+
}
|
|
15
|
+
export type SlotComponent<Component extends TComponent = TComponent> = SlotNamedComponent | DisplayNamedComponent<Component>;
|
|
16
|
+
export interface SlottedComponent<TProps = any, TSlotsRecordArg extends TSlotsRecord = TSlotsRecord> {
|
|
17
|
+
(props: TProps): ReactNode;
|
|
18
|
+
Slots: TSlotsRecordArg;
|
|
19
|
+
}
|
|
20
|
+
export type TSlotNodes<TSlotAliasArg extends TSlotAlias> = {
|
|
21
|
+
[Key in TSlotAliasArg]?: ReactElement<any>;
|
|
22
|
+
};
|
|
23
|
+
export type TUseSlotsResult<TSlotAliasArg extends TSlotAlias = TSlotAlias> = Readonly<[
|
|
24
|
+
slots: TSlotNodes<TSlotAliasArg>,
|
|
25
|
+
unmatchedChildren: ReactNode[],
|
|
26
|
+
invalidChildren: any[]
|
|
27
|
+
]>;
|
|
28
|
+
export interface IUseSlots {
|
|
29
|
+
<TSlotAliasArg extends TSlotAlias = TSlotAlias>(children: ReactNode, slotComponents: TSlotsRecord<TSlotAliasArg>): TUseSlotsResult<TSlotAliasArg>;
|
|
30
|
+
}
|
|
31
|
+
export type PotentialSlotComponent = string | SlotComponent | TComponent;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleanweb/oore",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-alpha.0",
|
|
4
4
|
"description": "A library of helpers for writing cleaner React function components with object-oriented patterns.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20"
|
|
@@ -10,15 +10,11 @@
|
|
|
10
10
|
".npmrc"
|
|
11
11
|
],
|
|
12
12
|
"main": "build/index.js",
|
|
13
|
-
"//exports/.": {
|
|
14
|
-
"require": "./src/index.cjs",
|
|
15
|
-
"import": "./src/index.mjs"
|
|
16
|
-
},
|
|
17
|
-
"//type": "module",
|
|
18
13
|
"exports": {
|
|
19
14
|
".": "./build/classy/index.js",
|
|
20
15
|
"./base": "./build/base/index.js",
|
|
21
16
|
"./helpers": "./build/helpers/index.js",
|
|
17
|
+
"./slots": "./build/slots/index.js",
|
|
22
18
|
"./all": "./build/index.js"
|
|
23
19
|
},
|
|
24
20
|
"scripts": {
|