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,8 @@
import type { IRenderFunction } from '../IRenderFunction';
/**
* Composes two 'render functions' to produce a final render function that renders
* the outer function, passing the inner function as 'default render'. The inner function
* is then passed the original 'default render' prop.
* @public
*/
export declare function composeRenderFunction<TProps>(outer: IRenderFunction<TProps>, inner: IRenderFunction<TProps>): IRenderFunction<TProps>;
@@ -0,0 +1,25 @@
import { createMemoizer } from '../memoize';
function createComposedRenderFunction(outer) {
var outerMemoizer = createMemoizer(function (inner) {
var innerMemoizer = createMemoizer(function (defaultRender) {
return function (innerProps) {
return inner(innerProps, defaultRender);
};
});
return function (outerProps, defaultRender) {
return outer(outerProps, defaultRender ? innerMemoizer(defaultRender) : inner);
};
});
return outerMemoizer;
}
var memoizer = createMemoizer(createComposedRenderFunction);
/**
* Composes two 'render functions' to produce a final render function that renders
* the outer function, passing the inner function as 'default render'. The inner function
* is then passed the original 'default render' prop.
* @public
*/
export function composeRenderFunction(outer, inner) {
return memoizer(outer)(inner);
}
//# sourceMappingURL=composeRenderFunction.js.map
@@ -0,0 +1 @@
{"version":3,"file":"composeRenderFunction.js","sourceRoot":"../src/","sources":["renderFunction/composeRenderFunction.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAO5C,SAAS,4BAA4B,CACnC,KAA8B;IAE9B,IAAM,aAAa,GAAG,cAAc,CAAC,UAAC,KAA8B;QAClE,IAAM,aAAa,GAAG,cAAc,CAAC,UAAC,aAAsC;YAC1E,OAAO,UAAC,UAAmB;gBACzB,OAAO,KAAK,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;YAC1C,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO,UAAC,UAAmB,EAAE,aAAuC;YAClE,OAAO,KAAK,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACjF,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,IAAM,QAAQ,GAAG,cAAc,CAA0B,4BAA4B,CAAC,CAAC;AAEvF;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAA8B,EAC9B,KAA8B;IAE9B,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC","sourcesContent":["import { createMemoizer } from '../memoize';\nimport type { IRenderFunction } from '../IRenderFunction';\n\ninterface IRenderFunctionComposer {\n <TProps>(outer: IRenderFunction<TProps>): (inner: IRenderFunction<TProps>) => IRenderFunction<TProps>;\n}\n\nfunction createComposedRenderFunction<TProps>(\n outer: IRenderFunction<TProps>,\n): (inner: IRenderFunction<TProps>) => IRenderFunction<TProps> {\n const outerMemoizer = createMemoizer((inner: IRenderFunction<TProps>) => {\n const innerMemoizer = createMemoizer((defaultRender: IRenderFunction<TProps>) => {\n return (innerProps?: TProps) => {\n return inner(innerProps, defaultRender);\n };\n });\n\n return (outerProps?: TProps, defaultRender?: IRenderFunction<TProps>) => {\n return outer(outerProps, defaultRender ? innerMemoizer(defaultRender) : inner);\n };\n });\n\n return outerMemoizer;\n}\n\nconst memoizer = createMemoizer<IRenderFunctionComposer>(createComposedRenderFunction);\n\n/**\n * Composes two 'render functions' to produce a final render function that renders\n * the outer function, passing the inner function as 'default render'. The inner function\n * is then passed the original 'default render' prop.\n * @public\n */\nexport function composeRenderFunction<TProps>(\n outer: IRenderFunction<TProps>,\n inner: IRenderFunction<TProps>,\n): IRenderFunction<TProps> {\n return memoizer(outer)(inner);\n}\n"]}
@@ -0,0 +1 @@
export {};
@@ -0,0 +1,45 @@
import * as React from 'react';
import { render } from '@testing-library/react';
import { composeRenderFunction } from './composeRenderFunction';
var renderBase = function (props) {
return React.createElement("div", { "data-value": props.value });
};
var renderDecoratorA = function (props, defaultRender) {
if (!props) {
return null;
}
return React.createElement("div", { "data-a": "a" }, defaultRender ? defaultRender(props) : null);
};
var renderDecoratorB = function (props, defaultRender) {
if (!props) {
return null;
}
return React.createElement("div", { "data-b": "b" }, defaultRender ? defaultRender(props) : null);
};
describe('composeComponentAs', function () {
it('passes Base to DecoratorA', function () {
var renderDecoratorAWithBase = composeRenderFunction(renderDecoratorA, renderBase);
var container = render(React.createElement(React.Fragment, null, renderDecoratorAWithBase({ value: 'test' }))).container;
expect(container.firstChild).toMatchSnapshot();
});
it('passes Base to DecoratorB through DecoratorA', function () {
var renderDecoratorAAndBWithBase = composeRenderFunction(renderDecoratorA, composeRenderFunction(renderDecoratorB, renderBase));
var container = render(React.createElement(React.Fragment, null, renderDecoratorAAndBWithBase({ value: 'test' }))).container;
expect(container.firstChild).toMatchSnapshot();
});
it('passes Base as defaultRender to DecoratorB through DecoratorA', function () {
var renderDecoratorAAroundB = composeRenderFunction(renderDecoratorA, renderDecoratorB);
var container = render(React.createElement(React.Fragment, null, renderDecoratorAAroundB({ value: 'test' }, renderBase))).container;
expect(container.firstChild).toMatchSnapshot();
});
it('renders without defaultRender', function () {
var renderDecoratorAAroundB = composeRenderFunction(renderDecoratorA, renderDecoratorB);
var container = render(React.createElement(React.Fragment, null, renderDecoratorAAroundB({ value: 'test' }))).container;
expect(container.firstChild).toMatchSnapshot();
});
it('avoids recomposing already-composed components', function () {
var renderDecoratorAAroundB = composeRenderFunction(renderDecoratorA, renderDecoratorB);
expect(composeRenderFunction(renderDecoratorA, renderDecoratorB)).toBe(renderDecoratorAAroundB);
});
});
//# sourceMappingURL=composeRenderFunction.test.js.map
@@ -0,0 +1 @@
{"version":3,"file":"composeRenderFunction.test.js","sourceRoot":"../src/","sources":["renderFunction/composeRenderFunction.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { render } from '@testing-library/react';\nimport { composeRenderFunction } from './composeRenderFunction';\nimport type { IRenderFunction } from '../IRenderFunction';\n\nimport type { JSXElement } from '../jsx';\n\ninterface IExampleProps {\n value: string;\n}\n\nconst renderBase = (props: IExampleProps): JSXElement | null => {\n return <div data-value={props.value} />;\n};\n\nconst renderDecoratorA = (props?: IExampleProps, defaultRender?: IRenderFunction<IExampleProps>): JSXElement | null => {\n if (!props) {\n return null;\n }\n\n return <div data-a=\"a\">{defaultRender ? defaultRender(props) : null}</div>;\n};\n\nconst renderDecoratorB = (props?: IExampleProps, defaultRender?: IRenderFunction<IExampleProps>): JSXElement | null => {\n if (!props) {\n return null;\n }\n\n return <div data-b=\"b\">{defaultRender ? defaultRender(props) : null}</div>;\n};\n\ndescribe('composeComponentAs', () => {\n it('passes Base to DecoratorA', () => {\n const renderDecoratorAWithBase = composeRenderFunction(renderDecoratorA, renderBase);\n\n const { container } = render(<>{renderDecoratorAWithBase({ value: 'test' })}</>);\n expect(container.firstChild).toMatchSnapshot();\n });\n\n it('passes Base to DecoratorB through DecoratorA', () => {\n const renderDecoratorAAndBWithBase = composeRenderFunction(\n renderDecoratorA,\n composeRenderFunction(renderDecoratorB, renderBase),\n );\n\n const { container } = render(<>{renderDecoratorAAndBWithBase({ value: 'test' })}</>);\n expect(container.firstChild).toMatchSnapshot();\n });\n\n it('passes Base as defaultRender to DecoratorB through DecoratorA', () => {\n const renderDecoratorAAroundB = composeRenderFunction(renderDecoratorA, renderDecoratorB);\n\n const { container } = render(<>{renderDecoratorAAroundB({ value: 'test' }, renderBase)}</>);\n expect(container.firstChild).toMatchSnapshot();\n });\n\n it('renders without defaultRender', () => {\n const renderDecoratorAAroundB = composeRenderFunction(renderDecoratorA, renderDecoratorB);\n\n const { container } = render(<>{renderDecoratorAAroundB({ value: 'test' })}</>);\n expect(container.firstChild).toMatchSnapshot();\n });\n\n it('avoids recomposing already-composed components', () => {\n const renderDecoratorAAroundB = composeRenderFunction(renderDecoratorA, renderDecoratorB);\n\n expect(composeRenderFunction(renderDecoratorA, renderDecoratorB)).toBe(renderDecoratorAAroundB);\n });\n});\n"]}