From ab582fd114fe702ec7fde134b2c2a60fee740f4c Mon Sep 17 00:00:00 2001 From: ncpa0cpl Date: Sun, 9 Jul 2023 21:04:28 +0200 Subject: [PATCH] feat: added helper methods to the context: Provider and Consumer --- .../render-to-html.test.tsx.snap | 15 +++++++ __tests__/html-parser/render-to-html.test.tsx | 44 +++++++++++++++++++ src/component-api/component-api.ts | 21 +++++++++ 3 files changed, 80 insertions(+) diff --git a/__tests__/html-parser/__snapshots__/render-to-html.test.tsx.snap b/__tests__/html-parser/__snapshots__/render-to-html.test.tsx.snap index 2c96c8d..302a49d 100644 --- a/__tests__/html-parser/__snapshots__/render-to-html.test.tsx.snap +++ b/__tests__/html-parser/__snapshots__/render-to-html.test.tsx.snap @@ -112,6 +112,21 @@ exports[`renderToHTML should correctly render jsx with arrays in between element " `; +exports[`renderToHTML should properly handle context data Provider and Consumer 1`] = ` +" + +
+
no value
+ no value +
FOO
+ FOO +
BAR
+ BAR +
+ +" +`; + exports[`renderToHTML should properly handle context data close-by providers should not interfere with each other 1`] = ` " diff --git a/__tests__/html-parser/render-to-html.test.tsx b/__tests__/html-parser/render-to-html.test.tsx index df38ccc..d9182a7 100644 --- a/__tests__/html-parser/render-to-html.test.tsx +++ b/__tests__/html-parser/render-to-html.test.tsx @@ -798,6 +798,50 @@ describe("renderToHTML", () => { expect(html).toMatchSnapshot(); }); + + it("Provider and Consumer", () => { + const MagicalContext = defineContext(); + + const Foo: JSXTE.Component<{ id: string }> = (props, { ctx }) => { + const value = ctx.get(MagicalContext) ?? "no value"; + return ( +
+ {value} +
+ ); + }; + + const App = () => { + return ( + + +
+ + {v ?? "no value"}} + /> + + + {v}} + /> + + + {v}} + /> + + +
+ + + ); + }; + + const html = renderToHtml(); + + expect(html).toMatchSnapshot(); + }); }); describe("ErrorBoundary", () => { diff --git a/src/component-api/component-api.ts b/src/component-api/component-api.ts index 287b41d..24cf126 100644 --- a/src/component-api/component-api.ts +++ b/src/component-api/component-api.ts @@ -3,6 +3,7 @@ import { jsxElemToHtmlSync, type RendererInternalOptions, } from "../html-parser/jsx-elem-to-html"; +import { jsx } from "../jsx-runtime"; export class ContextAccessor { public static clone(original: ContextAccessor): ContextAccessor { @@ -146,6 +147,26 @@ export class ComponentApi { export class ContextDefinition { id = Symbol(); + + Provider = ( + props: JSXTE.PropsWithChildren<{ + value: T; + }>, + componentApi: ComponentApi + ) => { + componentApi.ctx.set(this, props.value); + return jsx("", { children: props.children }); + }; + + Consumer = ( + props: JSXTE.PropsWithChildren<{ + render: (value?: T) => JSX.Element; + }>, + componentApi: ComponentApi + ) => { + const value = componentApi.ctx.get(this); + return props.render(value); + }; } export const defineContext = () => new ContextDefinition();