diff --git a/package-lock.json b/package-lock.json index 7ffe0c3..f7be1b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@prismicio/react", - "version": "2.0.2", + "version": "2.0.3-debug.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@prismicio/react", - "version": "2.0.2", + "version": "2.0.3-debug.0", "license": "Apache-2.0", "dependencies": { "@prismicio/helpers": "^2.0.0", @@ -46,6 +46,7 @@ "siroc": "^0.16.0", "standard-version": "^9.3.2", "ts-eager": "^2.0.2", + "type-fest": "^2.9.0", "typescript": "^4.5.4" }, "engines": { @@ -4788,6 +4789,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globby": { "version": "11.0.4", "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", @@ -9968,12 +9981,12 @@ } }, "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.9.0.tgz", + "integrity": "sha512-uC0hJKi7eAGXUJ/YKk53RhnKxMwzHWgzf4t92oz8Qez28EBgVTfpDTB59y9hMYLzc/Wl85cD7Tv1hLZZoEJtrg==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -14403,6 +14416,14 @@ "dev": true, "requires": { "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } } }, "globby": { @@ -18280,9 +18301,9 @@ "dev": true }, "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.9.0.tgz", + "integrity": "sha512-uC0hJKi7eAGXUJ/YKk53RhnKxMwzHWgzf4t92oz8Qez28EBgVTfpDTB59y9hMYLzc/Wl85cD7Tv1hLZZoEJtrg==", "dev": true }, "typedarray": { diff --git a/package.json b/package.json index 8887485..dc5ca51 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "siroc": "^0.16.0", "standard-version": "^9.3.2", "ts-eager": "^2.0.2", + "type-fest": "^2.9.0", "typescript": "^4.5.4" }, "peerDependencies": { diff --git a/src/SliceZone.tsx b/src/SliceZone.tsx index 761ebca..f2607b3 100644 --- a/src/SliceZone.tsx +++ b/src/SliceZone.tsx @@ -1,7 +1,9 @@ import * as React from "react"; import * as prismicT from "@prismicio/types"; +import type { PascalCase } from "type-fest"; import { __PRODUCTION__ } from "./lib/__PRODUCTION__"; +import { pascalCase } from "./lib/pascalCase"; /** * The minimum required properties to represent a Prismic Slice for the @@ -148,7 +150,7 @@ type SliceZoneResolverArgs = { /** * The name of the Slice. */ - sliceName: TSlice["slice_type"]; + sliceName: PascalCase; /** * The index of the Slice in the Slice Zone. @@ -249,7 +251,7 @@ export const SliceZone = ({ if (resolver) { const resolvedComp = resolver({ slice, - sliceName: slice.slice_type, + sliceName: pascalCase(slice.slice_type), i: index, }); @@ -270,7 +272,7 @@ export const SliceZone = ({ /> ); }); - }, [components, context, defaultComponent, slices]); + }, [components, context, defaultComponent, slices, resolver]); return <>{renderedSlices}; }; diff --git a/src/lib/pascalCase.ts b/src/lib/pascalCase.ts new file mode 100644 index 0000000..4c7e16a --- /dev/null +++ b/src/lib/pascalCase.ts @@ -0,0 +1,10 @@ +import type { PascalCase } from "type-fest"; + +export const pascalCase = (input: string): PascalCase => { + const camelCased = input.replace(/(?:-|_)(\w)/g, (_, c) => { + return c ? c.toUpperCase() : ""; + }); + + return (camelCased[0].toUpperCase() + + camelCased.slice(1)) as PascalCase; +}; diff --git a/test/SliceZone.test.tsx b/test/SliceZone.test.tsx index 042c3bb..568a67c 100644 --- a/test/SliceZone.test.tsx +++ b/test/SliceZone.test.tsx @@ -172,18 +172,32 @@ test.skip("TODO component does not warn in production", () => { }); test("renders components from a resolver function for backwards compatibility with next-slicezone", async (t) => { - const slices = [{ slice_type: "foo" }, { slice_type: "bar" }] as const; + const slices = [ + { + slice_type: "foo_bar", + }, + { + slice_type: "barFoo", + }, + { + slice_type: "baz-qux", + }, + ] as const; const resolver: SliceZoneResolver = ({ sliceName, }) => { switch (sliceName) { - case "foo": { - return (props) => ; + case "FooBar": { + return (props) => ; + } + + case "BarFoo": { + return (props) => ; } - case "bar": { - return (props) => ; + case "BazQux": { + return (props) => ; } } }; @@ -192,19 +206,26 @@ test("renders components from a resolver function for backwards compatibility wi const expected = renderJSON( <> + , );