first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
@@ -0,0 +1,9 @@
import type { IComponentAs } from '../IComponentAs';
/**
* Composes two components which conform to the `IComponentAs` specification; that is, two
* components which accept a `defaultRender` prop, which is a 'default' implementation of
* a component which accepts the same overall props.
*
* @public
*/
export declare function composeComponentAs<TProps extends {}>(outer: IComponentAs<TProps>, inner: IComponentAs<TProps>): IComponentAs<TProps>;
@@ -0,0 +1,38 @@
define(["require", "exports", "tslib", "react", "../memoize"], function (require, exports, tslib_1, React, memoize_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.composeComponentAs = composeComponentAs;
function createComposedComponent(outer) {
var Outer = outer;
var outerMemoizer = (0, memoize_1.createMemoizer)(function (inner) {
if (outer === inner) {
throw new Error('Attempted to compose a component with itself.');
}
var Inner = inner;
var innerMemoizer = (0, memoize_1.createMemoizer)(function (defaultRender) {
var InnerWithDefaultRender = function (innerProps) {
return React.createElement(Inner, tslib_1.__assign({}, innerProps, { defaultRender: defaultRender }));
};
return InnerWithDefaultRender;
});
var OuterWithDefaultRender = function (outerProps) {
var defaultRender = outerProps.defaultRender;
return React.createElement(Outer, tslib_1.__assign({}, outerProps, { defaultRender: defaultRender ? innerMemoizer(defaultRender) : Inner }));
};
return OuterWithDefaultRender;
});
return outerMemoizer;
}
var componentAsMemoizer = (0, memoize_1.createMemoizer)(createComposedComponent);
/**
* Composes two components which conform to the `IComponentAs` specification; that is, two
* components which accept a `defaultRender` prop, which is a 'default' implementation of
* a component which accepts the same overall props.
*
* @public
*/
function composeComponentAs(outer, inner) {
return componentAsMemoizer(outer)(inner);
}
});
//# sourceMappingURL=composeComponentAs.js.map
@@ -0,0 +1 @@
{"version":3,"file":"composeComponentAs.js","sourceRoot":"../src/","sources":["componentAs/composeComponentAs.tsx"],"names":[],"mappings":";;;IAuDA,gDAKC;IAlDD,SAAS,uBAAuB,CAC9B,KAA2B;QAE3B,IAAM,KAAK,GAAG,KAAK,CAAC;QAEpB,IAAM,aAAa,GAAG,IAAA,wBAAc,EAAC,UAAC,KAA2B;YAC/D,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;YACnE,CAAC;YAED,IAAM,KAAK,GAAG,KAAK,CAAC;YAEpB,IAAM,aAAa,GAAG,IAAA,wBAAc,EAAC,UAAC,aAAmC;gBACvE,IAAM,sBAAsB,GAAmD,UAC7E,UAAqC;oBAErC,OAAO,oBAAC,KAAK,uBAAK,UAAU,IAAE,aAAa,EAAE,aAAa,IAAI,CAAC;gBACjE,CAAC,CAAC;gBAEF,OAAO,sBAAsB,CAAC;YAChC,CAAC,CAAC,CAAC;YAEH,IAAM,sBAAsB,GAAmD,UAC7E,UAAqC;gBAE7B,IAAA,aAAa,GAAK,UAAU,cAAf,CAAgB;gBAErC,OAAO,oBAAC,KAAK,uBAAK,UAAU,IAAE,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;YACxG,CAAC,CAAC;YAEF,OAAO,sBAAsB,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,IAAM,mBAAmB,GAAG,IAAA,wBAAc,EAAsB,uBAAuB,CAAC,CAAC;IAEzF;;;;;;OAMG;IACH,SAAgB,kBAAkB,CAChC,KAA2B,EAC3B,KAA2B;QAE3B,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC","sourcesContent":["import * as React from 'react';\nimport { createMemoizer } from '../memoize';\nimport type { IComponentAs, IComponentAsProps } from '../IComponentAs';\n\nimport type { JSXElement } from '../jsx';\n\ninterface IComposeComponentAs {\n <TProps extends {}>(outer: IComponentAs<TProps>): (inner: IComponentAs<TProps>) => IComponentAs<TProps>;\n}\n\nfunction createComposedComponent<TProps extends {}>(\n outer: IComponentAs<TProps>,\n): (inner: IComponentAs<TProps>) => IComponentAs<TProps> {\n const Outer = outer;\n\n const outerMemoizer = createMemoizer((inner: IComponentAs<TProps>) => {\n if (outer === inner) {\n throw new Error('Attempted to compose a component with itself.');\n }\n\n const Inner = inner;\n\n const innerMemoizer = createMemoizer((defaultRender: IComponentAs<TProps>) => {\n const InnerWithDefaultRender: React.ComponentType<IComponentAsProps<TProps>> = (\n innerProps: IComponentAsProps<TProps>,\n ): JSXElement => {\n return <Inner {...innerProps} defaultRender={defaultRender} />;\n };\n\n return InnerWithDefaultRender;\n });\n\n const OuterWithDefaultRender: React.ComponentType<IComponentAsProps<TProps>> = (\n outerProps: IComponentAsProps<TProps>,\n ): JSXElement => {\n const { defaultRender } = outerProps;\n\n return <Outer {...outerProps} defaultRender={defaultRender ? innerMemoizer(defaultRender) : Inner} />;\n };\n\n return OuterWithDefaultRender;\n });\n\n return outerMemoizer;\n}\n\nconst componentAsMemoizer = createMemoizer<IComposeComponentAs>(createComposedComponent);\n\n/**\n * Composes two components which conform to the `IComponentAs` specification; that is, two\n * components which accept a `defaultRender` prop, which is a 'default' implementation of\n * a component which accepts the same overall props.\n *\n * @public\n */\nexport function composeComponentAs<TProps extends {}>(\n outer: IComponentAs<TProps>,\n inner: IComponentAs<TProps>,\n): IComponentAs<TProps> {\n return componentAsMemoizer(outer)(inner);\n}\n"]}
@@ -0,0 +1 @@
export {};
@@ -0,0 +1,42 @@
define(["require", "exports", "tslib", "react", "@testing-library/react", "./composeComponentAs"], function (require, exports, tslib_1, React, react_1, composeComponentAs_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Base = function (props) {
return React.createElement("div", { "data-value": props.value });
};
var DecoratorA = function (props) {
var DefaultRender = props.defaultRender, exampleProps = tslib_1.__rest(props, ["defaultRender"]);
return React.createElement("div", { "data-a": "a" }, DefaultRender ? React.createElement(DefaultRender, tslib_1.__assign({}, exampleProps)) : null);
};
var DecoratorB = function (props) {
var DefaultRender = props.defaultRender, exampleProps = tslib_1.__rest(props, ["defaultRender"]);
return React.createElement("div", { "data-b": "b" }, DefaultRender ? React.createElement(DefaultRender, tslib_1.__assign({}, exampleProps)) : null);
};
describe('composeComponentAs', function () {
it('passes Base to DecoratorA', function () {
var DecoratorAWithBase = (0, composeComponentAs_1.composeComponentAs)(DecoratorA, Base);
var component = (0, react_1.render)(React.createElement(DecoratorAWithBase, { value: "test" }));
expect(component.container.firstChild).toMatchSnapshot();
});
it('passes Base to DecoratorB through DecoratorA', function () {
var DecoratorAAndBWithBase = (0, composeComponentAs_1.composeComponentAs)(DecoratorA, (0, composeComponentAs_1.composeComponentAs)(DecoratorB, Base));
var component = (0, react_1.render)(React.createElement(DecoratorAAndBWithBase, { value: "test" }));
expect(component.container.firstChild).toMatchSnapshot();
});
it('passes Base as defaultRender to DecoratorB through DecoratorA', function () {
var DecoratorAAroundB = (0, composeComponentAs_1.composeComponentAs)(DecoratorA, DecoratorB);
var component = (0, react_1.render)(React.createElement(DecoratorAAroundB, { value: "test", defaultRender: Base }));
expect(component.container.firstChild).toMatchSnapshot();
});
it('renders without defaultRender', function () {
var DecoratorAAroundB = (0, composeComponentAs_1.composeComponentAs)(DecoratorA, DecoratorB);
var component = (0, react_1.render)(React.createElement(DecoratorAAroundB, { value: "test" }));
expect(component.container.firstChild).toMatchSnapshot();
});
it('avoids recomposing already-composed components', function () {
var DecoratorAAroundB = (0, composeComponentAs_1.composeComponentAs)(DecoratorA, DecoratorB);
expect((0, composeComponentAs_1.composeComponentAs)(DecoratorA, DecoratorB)).toBe(DecoratorAAroundB);
});
});
});
//# sourceMappingURL=composeComponentAs.test.js.map
@@ -0,0 +1 @@
{"version":3,"file":"composeComponentAs.test.js","sourceRoot":"../src/","sources":["componentAs/composeComponentAs.test.tsx"],"names":[],"mappings":";;;IAWA,IAAM,IAAI,GAAuC,UAAC,KAAoB;QACpE,OAAO,2CAAiB,KAAK,CAAC,KAAK,GAAI,CAAC;IAC1C,CAAC,CAAC;IAEF,IAAM,UAAU,GAA0D,UACxE,KAAuC;QAE/B,IAAe,aAAa,GAAsB,KAAK,cAA3B,EAAK,YAAY,kBAAK,KAAK,EAAzD,iBAAiD,CAAF,CAAW;QAEhE,OAAO,uCAAY,GAAG,IAAE,aAAa,CAAC,CAAC,CAAC,oBAAC,aAAa,uBAAK,YAAY,EAAI,CAAC,CAAC,CAAC,IAAI,CAAO,CAAC;IAC5F,CAAC,CAAC;IAEF,IAAM,UAAU,GAA0D,UACxE,KAAuC;QAE/B,IAAe,aAAa,GAAsB,KAAK,cAA3B,EAAK,YAAY,kBAAK,KAAK,EAAzD,iBAAiD,CAAF,CAAW;QAEhE,OAAO,uCAAY,GAAG,IAAE,aAAa,CAAC,CAAC,CAAC,oBAAC,aAAa,uBAAK,YAAY,EAAI,CAAC,CAAC,CAAC,IAAI,CAAO,CAAC;IAC5F,CAAC,CAAC;IAEF,QAAQ,CAAC,oBAAoB,EAAE;QAC7B,EAAE,CAAC,2BAA2B,EAAE;YAC9B,IAAM,kBAAkB,GAAG,IAAA,uCAAkB,EAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAChE,IAAM,SAAS,GAAG,IAAA,cAAM,EAAC,oBAAC,kBAAkB,IAAC,KAAK,EAAC,MAAM,GAAG,CAAC,CAAC;YAE9D,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,eAAe,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE;YACjD,IAAM,sBAAsB,GAAG,IAAA,uCAAkB,EAAC,UAAU,EAAE,IAAA,uCAAkB,EAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;YACpG,IAAM,SAAS,GAAG,IAAA,cAAM,EAAC,oBAAC,sBAAsB,IAAC,KAAK,EAAC,MAAM,GAAG,CAAC,CAAC;YAElE,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,eAAe,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE;YAClE,IAAM,iBAAiB,GAAG,IAAA,uCAAkB,EAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAErE,IAAM,SAAS,GAAG,IAAA,cAAM,EAAC,oBAAC,iBAAiB,IAAC,KAAK,EAAC,MAAM,EAAC,aAAa,EAAE,IAAI,GAAI,CAAC,CAAC;YAElF,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,eAAe,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE;YAClC,IAAM,iBAAiB,GAAG,IAAA,uCAAkB,EAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAErE,IAAM,SAAS,GAAG,IAAA,cAAM,EAAC,oBAAC,iBAAiB,IAAC,KAAK,EAAC,MAAM,GAAG,CAAC,CAAC;YAE7D,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,eAAe,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE;YACnD,IAAM,iBAAiB,GAAG,IAAA,uCAAkB,EAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAErE,MAAM,CAAC,IAAA,uCAAkB,EAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC","sourcesContent":["import * as React from 'react';\nimport { render } from '@testing-library/react';\nimport { composeComponentAs } from './composeComponentAs';\nimport type { IComponentAsProps } from '../IComponentAs';\n\nimport type { JSXElement } from '../jsx';\n\ninterface IExampleProps {\n value: string;\n}\n\nconst Base: React.ComponentType<IExampleProps> = (props: IExampleProps): JSXElement | null => {\n return <div data-value={props.value} />;\n};\n\nconst DecoratorA: React.ComponentType<IComponentAsProps<IExampleProps>> = (\n props: IComponentAsProps<IExampleProps>,\n): JSXElement | null => {\n const { defaultRender: DefaultRender, ...exampleProps } = props;\n\n return <div data-a=\"a\">{DefaultRender ? <DefaultRender {...exampleProps} /> : null}</div>;\n};\n\nconst DecoratorB: React.ComponentType<IComponentAsProps<IExampleProps>> = (\n props: IComponentAsProps<IExampleProps>,\n): JSXElement | null => {\n const { defaultRender: DefaultRender, ...exampleProps } = props;\n\n return <div data-b=\"b\">{DefaultRender ? <DefaultRender {...exampleProps} /> : null}</div>;\n};\n\ndescribe('composeComponentAs', () => {\n it('passes Base to DecoratorA', () => {\n const DecoratorAWithBase = composeComponentAs(DecoratorA, Base);\n const component = render(<DecoratorAWithBase value=\"test\" />);\n\n expect(component.container.firstChild).toMatchSnapshot();\n });\n\n it('passes Base to DecoratorB through DecoratorA', () => {\n const DecoratorAAndBWithBase = composeComponentAs(DecoratorA, composeComponentAs(DecoratorB, Base));\n const component = render(<DecoratorAAndBWithBase value=\"test\" />);\n\n expect(component.container.firstChild).toMatchSnapshot();\n });\n\n it('passes Base as defaultRender to DecoratorB through DecoratorA', () => {\n const DecoratorAAroundB = composeComponentAs(DecoratorA, DecoratorB);\n\n const component = render(<DecoratorAAroundB value=\"test\" defaultRender={Base} />);\n\n expect(component.container.firstChild).toMatchSnapshot();\n });\n\n it('renders without defaultRender', () => {\n const DecoratorAAroundB = composeComponentAs(DecoratorA, DecoratorB);\n\n const component = render(<DecoratorAAroundB value=\"test\" />);\n\n expect(component.container.firstChild).toMatchSnapshot();\n });\n\n it('avoids recomposing already-composed components', () => {\n const DecoratorAAroundB = composeComponentAs(DecoratorA, DecoratorB);\n\n expect(composeComponentAs(DecoratorA, DecoratorB)).toBe(DecoratorAAroundB);\n });\n});\n"]}