@prismicio/react 2.9.2 → 3.0.0-alpha.1

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.
Files changed (191) hide show
  1. package/README.md +10 -11
  2. package/dist/PrismicImage.d.ts +18 -633
  3. package/dist/PrismicImage.js +32 -33
  4. package/dist/PrismicImage.js.map +1 -1
  5. package/dist/PrismicLink.d.ts +77 -6
  6. package/dist/PrismicLink.js +42 -7
  7. package/dist/PrismicLink.js.map +1 -1
  8. package/dist/PrismicRichText.d.ts +117 -4
  9. package/dist/PrismicRichText.js +74 -8
  10. package/dist/PrismicRichText.js.map +1 -1
  11. package/dist/PrismicText.d.ts +9 -14
  12. package/dist/PrismicText.js +13 -14
  13. package/dist/PrismicText.js.map +1 -1
  14. package/dist/PrismicToolbar.d.ts +3 -12
  15. package/dist/PrismicToolbar.js +7 -9
  16. package/dist/PrismicToolbar.js.map +1 -1
  17. package/dist/SliceZone.d.ts +16 -70
  18. package/dist/SliceZone.js +17 -38
  19. package/dist/SliceZone.js.map +1 -1
  20. package/dist/index.d.ts +13 -21
  21. package/dist/index.js +2 -29
  22. package/dist/index.js.map +1 -1
  23. package/dist/lib/devMsg.d.ts +2 -2
  24. package/dist/lib/devMsg.js +2 -2
  25. package/dist/lib/devMsg.js.map +1 -1
  26. package/dist/package.json.js +1 -1
  27. package/package.json +54 -71
  28. package/src/PrismicImage.tsx +80 -65
  29. package/src/PrismicLink.tsx +196 -26
  30. package/src/PrismicRichText.tsx +333 -32
  31. package/src/PrismicText.tsx +25 -31
  32. package/src/PrismicToolbar.tsx +9 -29
  33. package/src/SliceZone.tsx +59 -151
  34. package/src/index.ts +17 -53
  35. package/src/lib/devMsg.ts +3 -3
  36. package/dist/PrismicImage.cjs +0 -68
  37. package/dist/PrismicImage.cjs.map +0 -1
  38. package/dist/PrismicLink.cjs +0 -29
  39. package/dist/PrismicLink.cjs.map +0 -1
  40. package/dist/PrismicProvider.cjs +0 -41
  41. package/dist/PrismicProvider.cjs.map +0 -1
  42. package/dist/PrismicProvider.d.ts +0 -83
  43. package/dist/PrismicProvider.js +0 -24
  44. package/dist/PrismicProvider.js.map +0 -1
  45. package/dist/PrismicRichText.cjs +0 -30
  46. package/dist/PrismicRichText.cjs.map +0 -1
  47. package/dist/PrismicText.cjs +0 -44
  48. package/dist/PrismicText.cjs.map +0 -1
  49. package/dist/PrismicToolbar.cjs +0 -43
  50. package/dist/PrismicToolbar.cjs.map +0 -1
  51. package/dist/SliceZone.cjs +0 -53
  52. package/dist/SliceZone.cjs.map +0 -1
  53. package/dist/_node_modules/@prismicio/client/dist/errors/PrismicError.cjs +0 -16
  54. package/dist/_node_modules/@prismicio/client/dist/errors/PrismicError.cjs.map +0 -1
  55. package/dist/_node_modules/@prismicio/client/dist/errors/PrismicError.js +0 -16
  56. package/dist/_node_modules/@prismicio/client/dist/errors/PrismicError.js.map +0 -1
  57. package/dist/_node_modules/@prismicio/client/dist/getToolbarSrc.cjs +0 -13
  58. package/dist/_node_modules/@prismicio/client/dist/getToolbarSrc.cjs.map +0 -1
  59. package/dist/_node_modules/@prismicio/client/dist/getToolbarSrc.js +0 -13
  60. package/dist/_node_modules/@prismicio/client/dist/getToolbarSrc.js.map +0 -1
  61. package/dist/_node_modules/@prismicio/client/dist/helpers/asImagePixelDensitySrcSet.cjs +0 -22
  62. package/dist/_node_modules/@prismicio/client/dist/helpers/asImagePixelDensitySrcSet.cjs.map +0 -1
  63. package/dist/_node_modules/@prismicio/client/dist/helpers/asImagePixelDensitySrcSet.js +0 -22
  64. package/dist/_node_modules/@prismicio/client/dist/helpers/asImagePixelDensitySrcSet.js.map +0 -1
  65. package/dist/_node_modules/@prismicio/client/dist/helpers/asImageWidthSrcSet.cjs +0 -46
  66. package/dist/_node_modules/@prismicio/client/dist/helpers/asImageWidthSrcSet.cjs.map +0 -1
  67. package/dist/_node_modules/@prismicio/client/dist/helpers/asImageWidthSrcSet.js +0 -46
  68. package/dist/_node_modules/@prismicio/client/dist/helpers/asImageWidthSrcSet.js.map +0 -1
  69. package/dist/_node_modules/@prismicio/client/dist/helpers/asLink.cjs +0 -47
  70. package/dist/_node_modules/@prismicio/client/dist/helpers/asLink.cjs.map +0 -1
  71. package/dist/_node_modules/@prismicio/client/dist/helpers/asLink.js +0 -47
  72. package/dist/_node_modules/@prismicio/client/dist/helpers/asLink.js.map +0 -1
  73. package/dist/_node_modules/@prismicio/client/dist/helpers/asLinkAttrs.cjs +0 -28
  74. package/dist/_node_modules/@prismicio/client/dist/helpers/asLinkAttrs.cjs.map +0 -1
  75. package/dist/_node_modules/@prismicio/client/dist/helpers/asLinkAttrs.js +0 -28
  76. package/dist/_node_modules/@prismicio/client/dist/helpers/asLinkAttrs.js.map +0 -1
  77. package/dist/_node_modules/@prismicio/client/dist/helpers/asText.cjs +0 -21
  78. package/dist/_node_modules/@prismicio/client/dist/helpers/asText.cjs.map +0 -1
  79. package/dist/_node_modules/@prismicio/client/dist/helpers/asText.js +0 -21
  80. package/dist/_node_modules/@prismicio/client/dist/helpers/asText.js.map +0 -1
  81. package/dist/_node_modules/@prismicio/client/dist/helpers/documentToLinkField.cjs +0 -27
  82. package/dist/_node_modules/@prismicio/client/dist/helpers/documentToLinkField.cjs.map +0 -1
  83. package/dist/_node_modules/@prismicio/client/dist/helpers/documentToLinkField.js +0 -27
  84. package/dist/_node_modules/@prismicio/client/dist/helpers/documentToLinkField.js.map +0 -1
  85. package/dist/_node_modules/@prismicio/client/dist/helpers/isFilled.cjs +0 -24
  86. package/dist/_node_modules/@prismicio/client/dist/helpers/isFilled.cjs.map +0 -1
  87. package/dist/_node_modules/@prismicio/client/dist/helpers/isFilled.js +0 -24
  88. package/dist/_node_modules/@prismicio/client/dist/helpers/isFilled.js.map +0 -1
  89. package/dist/_node_modules/@prismicio/client/dist/isRepositoryName.cjs +0 -7
  90. package/dist/_node_modules/@prismicio/client/dist/isRepositoryName.cjs.map +0 -1
  91. package/dist/_node_modules/@prismicio/client/dist/isRepositoryName.js +0 -7
  92. package/dist/_node_modules/@prismicio/client/dist/isRepositoryName.js.map +0 -1
  93. package/dist/_node_modules/@prismicio/client/dist/lib/isInternalURL.cjs +0 -9
  94. package/dist/_node_modules/@prismicio/client/dist/lib/isInternalURL.cjs.map +0 -1
  95. package/dist/_node_modules/@prismicio/client/dist/lib/isInternalURL.js +0 -9
  96. package/dist/_node_modules/@prismicio/client/dist/lib/isInternalURL.js.map +0 -1
  97. package/dist/_node_modules/@prismicio/client/dist/richtext/asText.cjs +0 -13
  98. package/dist/_node_modules/@prismicio/client/dist/richtext/asText.cjs.map +0 -1
  99. package/dist/_node_modules/@prismicio/client/dist/richtext/asText.js +0 -13
  100. package/dist/_node_modules/@prismicio/client/dist/richtext/asText.js.map +0 -1
  101. package/dist/_node_modules/@prismicio/client/dist/types/value/link.cjs +0 -10
  102. package/dist/_node_modules/@prismicio/client/dist/types/value/link.cjs.map +0 -1
  103. package/dist/_node_modules/@prismicio/client/dist/types/value/link.js +0 -10
  104. package/dist/_node_modules/@prismicio/client/dist/types/value/link.js.map +0 -1
  105. package/dist/_node_modules/imgix-url-builder/dist/buildPixelDensitySrcSet.cjs +0 -10
  106. package/dist/_node_modules/imgix-url-builder/dist/buildPixelDensitySrcSet.cjs.map +0 -1
  107. package/dist/_node_modules/imgix-url-builder/dist/buildPixelDensitySrcSet.js +0 -10
  108. package/dist/_node_modules/imgix-url-builder/dist/buildPixelDensitySrcSet.js.map +0 -1
  109. package/dist/_node_modules/imgix-url-builder/dist/buildURL.cjs +0 -29
  110. package/dist/_node_modules/imgix-url-builder/dist/buildURL.cjs.map +0 -1
  111. package/dist/_node_modules/imgix-url-builder/dist/buildURL.js +0 -29
  112. package/dist/_node_modules/imgix-url-builder/dist/buildURL.js.map +0 -1
  113. package/dist/_node_modules/imgix-url-builder/dist/buildWidthSrcSet.cjs +0 -10
  114. package/dist/_node_modules/imgix-url-builder/dist/buildWidthSrcSet.cjs.map +0 -1
  115. package/dist/_node_modules/imgix-url-builder/dist/buildWidthSrcSet.js +0 -10
  116. package/dist/_node_modules/imgix-url-builder/dist/buildWidthSrcSet.js.map +0 -1
  117. package/dist/clientHooks.cjs +0 -40
  118. package/dist/clientHooks.cjs.map +0 -1
  119. package/dist/clientHooks.d.ts +0 -321
  120. package/dist/clientHooks.js +0 -40
  121. package/dist/clientHooks.js.map +0 -1
  122. package/dist/index.cjs +0 -48
  123. package/dist/index.cjs.map +0 -1
  124. package/dist/lib/devMsg.cjs +0 -8
  125. package/dist/lib/devMsg.cjs.map +0 -1
  126. package/dist/lib/isInternalURL.cjs +0 -9
  127. package/dist/lib/isInternalURL.cjs.map +0 -1
  128. package/dist/lib/isInternalURL.d.ts +0 -8
  129. package/dist/lib/isInternalURL.js +0 -9
  130. package/dist/lib/isInternalURL.js.map +0 -1
  131. package/dist/lib/pascalCase.cjs +0 -10
  132. package/dist/lib/pascalCase.cjs.map +0 -1
  133. package/dist/lib/pascalCase.d.ts +0 -26
  134. package/dist/lib/pascalCase.js +0 -10
  135. package/dist/lib/pascalCase.js.map +0 -1
  136. package/dist/package.json.cjs +0 -5
  137. package/dist/package.json.cjs.map +0 -1
  138. package/dist/react-server/PrismicLink.cjs +0 -59
  139. package/dist/react-server/PrismicLink.cjs.map +0 -1
  140. package/dist/react-server/PrismicLink.d.ts +0 -77
  141. package/dist/react-server/PrismicLink.js +0 -42
  142. package/dist/react-server/PrismicLink.js.map +0 -1
  143. package/dist/react-server/PrismicRichText.cjs +0 -102
  144. package/dist/react-server/PrismicRichText.cjs.map +0 -1
  145. package/dist/react-server/PrismicRichText.d.ts +0 -104
  146. package/dist/react-server/PrismicRichText.js +0 -84
  147. package/dist/react-server/PrismicRichText.js.map +0 -1
  148. package/dist/react-server/index.d.ts +0 -4
  149. package/dist/react-server/unsupported.cjs +0 -97
  150. package/dist/react-server/unsupported.cjs.map +0 -1
  151. package/dist/react-server/unsupported.d.ts +0 -22
  152. package/dist/react-server/unsupported.js +0 -97
  153. package/dist/react-server/unsupported.js.map +0 -1
  154. package/dist/react-server.cjs +0 -44
  155. package/dist/react-server.cjs.map +0 -1
  156. package/dist/react-server.js +0 -41
  157. package/dist/react-server.js.map +0 -1
  158. package/dist/types.d.ts +0 -19
  159. package/dist/usePrismicClient.cjs +0 -13
  160. package/dist/usePrismicClient.cjs.map +0 -1
  161. package/dist/usePrismicClient.d.ts +0 -11
  162. package/dist/usePrismicClient.js +0 -13
  163. package/dist/usePrismicClient.js.map +0 -1
  164. package/dist/usePrismicContext.cjs +0 -26
  165. package/dist/usePrismicContext.cjs.map +0 -1
  166. package/dist/usePrismicContext.d.ts +0 -8
  167. package/dist/usePrismicContext.js +0 -9
  168. package/dist/usePrismicContext.js.map +0 -1
  169. package/dist/usePrismicPreviewResolver.cjs +0 -44
  170. package/dist/usePrismicPreviewResolver.cjs.map +0 -1
  171. package/dist/usePrismicPreviewResolver.d.ts +0 -45
  172. package/dist/usePrismicPreviewResolver.js +0 -27
  173. package/dist/usePrismicPreviewResolver.js.map +0 -1
  174. package/dist/useStatefulPrismicClientMethod.cjs +0 -91
  175. package/dist/useStatefulPrismicClientMethod.cjs.map +0 -1
  176. package/dist/useStatefulPrismicClientMethod.d.ts +0 -44
  177. package/dist/useStatefulPrismicClientMethod.js +0 -74
  178. package/dist/useStatefulPrismicClientMethod.js.map +0 -1
  179. package/src/PrismicProvider.tsx +0 -132
  180. package/src/clientHooks.ts +0 -472
  181. package/src/lib/isInternalURL.ts +0 -14
  182. package/src/lib/pascalCase.ts +0 -79
  183. package/src/react-server/PrismicLink.tsx +0 -197
  184. package/src/react-server/PrismicRichText.tsx +0 -326
  185. package/src/react-server/index.ts +0 -38
  186. package/src/react-server/unsupported.ts +0 -184
  187. package/src/types.ts +0 -24
  188. package/src/usePrismicClient.ts +0 -30
  189. package/src/usePrismicContext.ts +0 -13
  190. package/src/usePrismicPreviewResolver.ts +0 -93
  191. package/src/useStatefulPrismicClientMethod.ts +0 -196
package/package.json CHANGED
@@ -1,113 +1,96 @@
1
1
  {
2
2
  "name": "@prismicio/react",
3
- "version": "2.9.2",
3
+ "version": "3.0.0-alpha.1",
4
4
  "description": "React components and hooks to fetch and present Prismic content",
5
5
  "keywords": [
6
6
  "typescript",
7
7
  "prismic",
8
- "react",
9
- "cms",
10
- "hook"
8
+ "react"
11
9
  ],
12
10
  "repository": {
13
11
  "type": "git",
14
- "url": "ssh://git@github.com/prismicio/prismic-react.git"
12
+ "url": "git+https://github.com/prismicio/prismic-react.git"
15
13
  },
16
14
  "license": "Apache-2.0",
17
15
  "author": "Prismic <contact@prismic.io> (https://prismic.io)",
18
16
  "sideEffects": false,
17
+ "type": "module",
19
18
  "exports": {
20
19
  ".": {
21
- "react-server": {
22
- "require": {
23
- "types": "./dist/react-server/index.d.ts",
24
- "default": "./dist/react-server.cjs"
25
- },
26
- "import": {
27
- "types": "./dist/react-server/index.d.ts",
28
- "default": "./dist/react-server.js"
29
- }
30
- },
31
- "default": {
32
- "require": {
33
- "types": "./dist/index.d.ts",
34
- "default": "./dist/index.cjs"
35
- },
36
- "import": {
37
- "types": "./dist/index.d.ts",
38
- "default": "./dist/index.js"
39
- }
40
- }
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
41
22
  },
42
23
  "./package.json": "./package.json"
43
24
  },
44
- "main": "./dist/index.cjs",
45
- "module": "./dist/index.js",
46
- "react-native": "./dist/index.js",
47
- "types": "./dist/index.d.ts",
25
+ "typesVersions": {
26
+ "*": {
27
+ "*": [
28
+ "./dist/index.d.ts"
29
+ ]
30
+ }
31
+ },
48
32
  "files": [
49
33
  "dist",
50
34
  "src"
51
35
  ],
36
+ "workspaces": [
37
+ ".",
38
+ "e2e-projects/*"
39
+ ],
52
40
  "scripts": {
53
41
  "build": "vite build",
54
42
  "dev": "vite build --watch",
43
+ "e2e": "playwright test",
44
+ "e2e:ui": "npm run e2e -- --ui",
55
45
  "format": "prettier --write .",
56
- "lint": "eslint --ext .js,.jsx,.ts,.tsx .",
57
- "types": "tsc --noEmit",
46
+ "lint": "eslint",
58
47
  "prepare": "npm run build",
59
48
  "release": "npm run build && npm run test && standard-version && git push --follow-tags && npm run build && npm publish",
60
- "release:alpha": "npm run build && npm run test && standard-version --release-as minor --prerelease alpha && git push --follow-tags && npm run build && npm publish --tag alpha",
61
- "release:alpha:dry": "standard-version --release-as minor --prerelease alpha --dry-run",
49
+ "release:alpha": "npm run build && npm run test && standard-version --release-as major --prerelease alpha && git push --follow-tags && npm run build && npm publish --tag alpha",
50
+ "release:alpha:dry": "standard-version --release-as major --prerelease alpha --dry-run",
62
51
  "release:dry": "standard-version --dry-run",
63
- "unit": "vitest run --coverage",
64
- "unit:watch": "vitest watch",
65
52
  "size": "size-limit",
66
- "test": "npm run lint && npm run types && npm run unit && npm run build && npm run size"
53
+ "test": "npm run lint && npm run types && npm run build && npm run e2e && npm run size && npm run e2e",
54
+ "types": "tsc --noEmit"
67
55
  },
68
56
  "dependencies": {
69
- "@prismicio/richtext": "^2.1.5"
57
+ "esm-env": "^1.2.2"
70
58
  },
71
59
  "devDependencies": {
72
- "@prismicio/client": "^7.11.0",
73
- "@prismicio/mock": "0.4.0",
74
- "@size-limit/preset-small-lib": "^8.2.4",
75
- "@testing-library/react": "^14.0.0",
76
- "@types/node-fetch": "^3.0.3",
77
- "@types/react": "^18.2.9",
78
- "@types/react-test-renderer": "^18.0.0",
79
- "@typescript-eslint/eslint-plugin": "^5.59.9",
80
- "@typescript-eslint/parser": "^5.59.9",
81
- "@vitejs/plugin-react": "^4.0.0",
82
- "@vitest/coverage-v8": "^0.32.0",
83
- "eslint": "^8.42.0",
84
- "eslint-config-prettier": "^8.8.0",
85
- "eslint-plugin-prettier": "^4.2.1",
86
- "eslint-plugin-react": "^7.32.2",
87
- "eslint-plugin-react-hooks": "^4.6.0",
88
- "eslint-plugin-tsdoc": "^0.2.17",
89
- "happy-dom": "^9.20.3",
90
- "msw": "^1.2.1",
91
- "node-fetch": "^3.3.1",
92
- "prettier": "^2.8.8",
93
- "prettier-plugin-jsdoc": "^0.4.2",
94
- "react": "^18.2.0",
95
- "react-dom": "^18.2.0",
96
- "react-test-renderer": "^18.2.0",
97
- "rollup-plugin-preserve-directives": "^0.2.0",
98
- "size-limit": "^8.2.4",
60
+ "@eslint/js": "^9.18.0",
61
+ "@playwright/test": "^1.49.1",
62
+ "@prismicio/client": "^7.12.0",
63
+ "@rollup/plugin-typescript": "^12.1.2",
64
+ "@size-limit/preset-small-lib": "^11.1.6",
65
+ "@types/react": "^19.0.7",
66
+ "@types/react-dom": "^19.0.3",
67
+ "@vitejs/plugin-react": "^4.3.4",
68
+ "dotenv": "^16.4.7",
69
+ "eslint": "^9.18.0",
70
+ "eslint-config-prettier": "^10.0.1",
71
+ "eslint-plugin-prettier": "^5.2.2",
72
+ "eslint-plugin-react": "^7.37.4",
73
+ "eslint-plugin-react-hooks": "^5.1.0",
74
+ "eslint-plugin-tsdoc": "^0.4.0",
75
+ "playwright": "^1.49.1",
76
+ "prettier": "^3.4.2",
77
+ "prettier-plugin-jsdoc": "^1.3.2",
78
+ "react": "^19.0.0",
79
+ "react-dom": "^19.0.0",
80
+ "rollup-plugin-preserve-directives": "^0.4.0",
81
+ "rollup-preserve-directives": "^1.1.3",
82
+ "size-limit": "^11.1.6",
99
83
  "standard-version": "^9.5.0",
100
- "typescript": "^5.0.4",
101
- "vite": "^4.3.9",
102
- "vite-plugin-sdk": "^0.1.1",
103
- "vitest": "^0.32.0"
84
+ "typescript": "^5.7.3",
85
+ "typescript-eslint": "^8.20.0",
86
+ "vite": "^6.0.7"
104
87
  },
105
88
  "peerDependencies": {
106
- "@prismicio/client": "^6 || ^7",
107
- "react": "^18 || ^19.0.0-rc.0"
89
+ "@prismicio/client": "^7",
90
+ "react": "^18 || ^19"
108
91
  },
109
92
  "engines": {
110
- "node": ">=12.7.0"
93
+ "node": ">=18"
111
94
  },
112
95
  "publishConfig": {
113
96
  "access": "public"
@@ -1,23 +1,36 @@
1
- import * as React from "react";
2
- import * as prismic from "@prismicio/client";
3
- import { ImgixURLParams } from "imgix-url-builder";
1
+ import {
2
+ ForwardedRef,
3
+ forwardRef,
4
+ type ComponentProps,
5
+ FC,
6
+ ReactNode,
7
+ } from "react";
8
+ import {
9
+ type ImageFieldImage,
10
+ asImagePixelDensitySrcSet,
11
+ asImageWidthSrcSet,
12
+ isFilled,
13
+ } from "@prismicio/client";
14
+ import { DEV } from "esm-env";
4
15
 
5
- import { devMsg } from "./lib/devMsg";
16
+ import { devMsg } from "./lib/devMsg.js";
6
17
 
7
- /**
8
- * Props for `<PrismicImage>`.
9
- */
18
+ type ImgixURLParams = Omit<
19
+ NonNullable<Parameters<typeof asImageWidthSrcSet>[1]>,
20
+ "widths"
21
+ > &
22
+ Omit<
23
+ NonNullable<Parameters<typeof asImagePixelDensitySrcSet>[1]>,
24
+ "pixelDensities"
25
+ >;
26
+
27
+ /** Props for `<PrismicImage>`. */
10
28
  export type PrismicImageProps = Omit<
11
- React.DetailedHTMLProps<
12
- React.ImgHTMLAttributes<HTMLImageElement>,
13
- HTMLImageElement
14
- >,
29
+ ComponentProps<"img">,
15
30
  "src" | "srcset" | "alt"
16
31
  > & {
17
- /**
18
- * The Prismic Image field or thumbnail to render.
19
- */
20
- field: prismic.ImageFieldImage | null | undefined;
32
+ /** The Prismic Image field or thumbnail to render. */
33
+ field: ImageFieldImage | null | undefined;
21
34
 
22
35
  /**
23
36
  * An object of Imgix URL API parameters to transform the image.
@@ -42,6 +55,12 @@ export type PrismicImageProps = Omit<
42
55
  * https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/alt#decorative_images
43
56
  */
44
57
  fallbackAlt?: "";
58
+
59
+ /**
60
+ * The value to be rendered when the field is empty. If a fallback is not
61
+ * given, `null` will be rendered.
62
+ */
63
+ fallback?: ReactNode;
45
64
  } & (
46
65
  | {
47
66
  /**
@@ -56,19 +75,13 @@ export type PrismicImageProps = Omit<
56
75
  * `"thumbnails"` as the `widths` prop.
57
76
  */
58
77
  widths?:
59
- | NonNullable<
60
- Parameters<typeof prismic.asImageWidthSrcSet>[1]
61
- >["widths"]
78
+ | NonNullable<Parameters<typeof asImageWidthSrcSet>[1]>["widths"]
62
79
  | "defaults";
63
- /**
64
- * Not used when the `widths` prop is used.
65
- */
80
+ /** Not used when the `widths` prop is used. */
66
81
  pixelDensities?: never;
67
82
  }
68
83
  | {
69
- /**
70
- * Not used when the `widths` prop is used.
71
- */
84
+ /** Not used when the `widths` prop is used. */
72
85
  widths?: never;
73
86
  /**
74
87
  * Pixel densities used to build a `srcset` value for the Image field.
@@ -78,7 +91,7 @@ export type PrismicImageProps = Omit<
78
91
  */
79
92
  pixelDensities:
80
93
  | NonNullable<
81
- Parameters<typeof prismic.asImagePixelDensitySrcSet>[1]
94
+ Parameters<typeof asImagePixelDensitySrcSet>[1]
82
95
  >["pixelDensities"]
83
96
  | "defaults";
84
97
  }
@@ -103,46 +116,50 @@ export type PrismicImageProps = Omit<
103
116
  *
104
117
  * @returns A responsive image component for the given Image field.
105
118
  */
106
- export const PrismicImage = React.forwardRef(function PrismicImage(
107
- {
108
- field,
109
- alt,
110
- fallbackAlt,
111
- imgixParams = {},
112
- widths,
113
- pixelDensities,
114
- ...restProps
115
- }: PrismicImageProps,
116
- ref: React.ForwardedRef<HTMLImageElement>,
117
- ): React.JSX.Element | null {
118
- if (
119
- typeof process !== "undefined" &&
120
- process.env.NODE_ENV === "development"
119
+ export const PrismicImage: FC<PrismicImageProps> = forwardRef(
120
+ function PrismicImage(
121
+ props: PrismicImageProps,
122
+ ref: ForwardedRef<HTMLImageElement>,
121
123
  ) {
122
- if (typeof alt === "string" && alt !== "") {
123
- console.warn(
124
- `[PrismicImage] The "alt" prop can only be used to declare an image as decorative by passing an empty string (alt="") but was provided a non-empty string. You can resolve this warning by removing the "alt" prop or changing it to alt="". For more details, see ${devMsg(
125
- "alt-must-be-an-empty-string",
126
- )}`,
127
- );
128
- }
124
+ const {
125
+ field,
126
+ alt,
127
+ fallbackAlt,
128
+ imgixParams = {},
129
+ widths,
130
+ pixelDensities,
131
+ fallback,
132
+ ...restProps
133
+ } = props;
129
134
 
130
- if (typeof fallbackAlt === "string" && fallbackAlt !== "") {
131
- console.warn(
132
- `[PrismicImage] The "fallbackAlt" prop can only be used to declare an image as decorative by passing an empty string (fallbackAlt="") but was provided a non-empty string. You can resolve this warning by removing the "fallbackAlt" prop or changing it to fallbackAlt="". For more details, see ${devMsg(
133
- "alt-must-be-an-empty-string",
134
- )}`,
135
- );
135
+ if (DEV) {
136
+ if (typeof alt === "string" && alt !== "") {
137
+ console.warn(
138
+ `[PrismicImage] The "alt" prop can only be used to declare an image as decorative by passing an empty string (alt="") but was provided a non-empty string. You can resolve this warning by removing the "alt" prop or changing it to alt="". For more details, see ${devMsg(
139
+ "alt-must-be-an-empty-string",
140
+ )}`,
141
+ );
142
+ }
143
+
144
+ if (typeof fallbackAlt === "string" && fallbackAlt !== "") {
145
+ console.warn(
146
+ `[PrismicImage] The "fallbackAlt" prop can only be used to declare an image as decorative by passing an empty string (fallbackAlt="") but was provided a non-empty string. You can resolve this warning by removing the "fallbackAlt" prop or changing it to fallbackAlt="". For more details, see ${devMsg(
147
+ "alt-must-be-an-empty-string",
148
+ )}`,
149
+ );
150
+ }
151
+
152
+ if (widths && pixelDensities) {
153
+ console.warn(
154
+ `[PrismicImage] Only one of "widths" or "pixelDensities" props can be provided. You can resolve this warning by removing either the "widths" or "pixelDensities" prop. "widths" will be used in this case.`,
155
+ );
156
+ }
136
157
  }
137
158
 
138
- if (widths && pixelDensities) {
139
- console.warn(
140
- `[PrismicImage] Only one of "widths" or "pixelDensities" props can be provided. You can resolve this warning by removing either the "widths" or "pixelDensities" prop. "widths" will be used in this case.`,
141
- );
159
+ if (!isFilled.imageThumbnail(field)) {
160
+ return <>{fallback}</>;
142
161
  }
143
- }
144
162
 
145
- if (prismic.isFilled.imageThumbnail(field)) {
146
163
  const resolvedImgixParams = imgixParams;
147
164
  for (const x in imgixParams) {
148
165
  if (resolvedImgixParams[x as keyof typeof resolvedImgixParams] === null) {
@@ -154,7 +171,7 @@ export const PrismicImage = React.forwardRef(function PrismicImage(
154
171
  let srcSet: string | undefined;
155
172
 
156
173
  if (widths || !pixelDensities) {
157
- const res = prismic.asImageWidthSrcSet(field, {
174
+ const res = asImageWidthSrcSet(field, {
158
175
  ...resolvedImgixParams,
159
176
  widths: widths === "defaults" ? undefined : widths,
160
177
  } as ImgixURLParams);
@@ -162,7 +179,7 @@ export const PrismicImage = React.forwardRef(function PrismicImage(
162
179
  src = res.src;
163
180
  srcSet = res.srcset;
164
181
  } else if (pixelDensities) {
165
- const res = prismic.asImagePixelDensitySrcSet(field, {
182
+ const res = asImagePixelDensitySrcSet(field, {
166
183
  ...resolvedImgixParams,
167
184
  pixelDensities:
168
185
  pixelDensities === "defaults" ? undefined : pixelDensities,
@@ -181,7 +198,5 @@ export const PrismicImage = React.forwardRef(function PrismicImage(
181
198
  {...restProps}
182
199
  />
183
200
  );
184
- } else {
185
- return null;
186
- }
187
- });
201
+ },
202
+ );
@@ -1,41 +1,211 @@
1
- "use client";
1
+ import {
2
+ ComponentProps,
3
+ ComponentType,
4
+ ElementType,
5
+ ForwardedRef,
6
+ HTMLAttributeAnchorTarget,
7
+ ReactNode,
8
+ forwardRef,
9
+ } from "react";
10
+ import {
11
+ type LinkField,
12
+ type LinkResolverFunction,
13
+ type PrismicDocument,
14
+ asLinkAttrs,
15
+ type AsLinkAttrsConfig,
16
+ } from "@prismicio/client";
17
+ import { DEV } from "esm-env";
2
18
 
3
- import * as React from "react";
19
+ import { devMsg } from "./lib/devMsg.js";
4
20
 
5
- import {
6
- PrismicLink as ServerPrismicLink,
7
- LinkProps,
8
- PrismicLinkProps,
9
- defaultComponent,
10
- } from "./react-server/PrismicLink";
21
+ /** The default component rendered for internal and external links. */
22
+ const defaultComponent = "a";
23
+
24
+ /** Props provided to a component when rendered with `<PrismicLink>`. */
25
+ export interface LinkProps {
26
+ /** The URL to link. */
27
+ href: string;
28
+
29
+ /**
30
+ * The `target` attribute for anchor elements. If the Prismic field is
31
+ * configured to open in a new window, this prop defaults to `_blank`.
32
+ */
33
+ target?: HTMLAttributeAnchorTarget;
34
+
35
+ /**
36
+ * The `rel` attribute for anchor elements. If the `target` prop is set to
37
+ * `"_blank"`, this prop defaults to `"noopener noreferrer"`.
38
+ */
39
+ rel?: string;
40
+
41
+ /** Children for the component. * */
42
+ children?: ReactNode;
43
+ }
44
+
45
+ export type PrismicLinkProps<
46
+ InternalComponentProps = ComponentProps<typeof defaultComponent>,
47
+ ExternalComponentProps = ComponentProps<typeof defaultComponent>,
48
+ > = Omit<
49
+ InternalComponentProps & ExternalComponentProps,
50
+ "rel" | "href" | "children"
51
+ > & {
52
+ /**
53
+ * The `rel` attribute for the link. By default, `"noreferrer"` is provided if
54
+ * the link's URL is external. This prop can be provided a function to use the
55
+ * link's metadata to determine the `rel` value.
56
+ */
57
+ rel?: string | AsLinkAttrsConfig["rel"];
58
+
59
+ /**
60
+ * The Link Resolver used to resolve links.
61
+ *
62
+ * @remarks
63
+ * If your app uses Route Resolvers when querying for your Prismic
64
+ * repository's content, a Link Resolver does not need to be provided.
65
+ *
66
+ * @see Learn about Link Resolvers and Route Resolvers {@link https://prismic.io/docs/core-concepts/link-resolver-route-resolver}
67
+ */
68
+ linkResolver?: LinkResolverFunction;
11
69
 
12
- import { usePrismicContext } from "./usePrismicContext";
70
+ /**
71
+ * The component rendered for internal URLs. Defaults to `<a>`.
72
+ *
73
+ * If your app uses a client-side router that requires a special Link
74
+ * component, provide the Link component to this prop.
75
+ */
76
+ internalComponent?: ElementType<InternalComponentProps>;
13
77
 
14
- export type { LinkProps, PrismicLinkProps };
78
+ /** The component rendered for external URLs. Defaults to `<a>`. */
79
+ externalComponent?: ComponentType<ExternalComponentProps>;
15
80
 
16
- export const PrismicLink = React.forwardRef(function PrismicLink<
17
- InternalComponentProps = React.ComponentProps<typeof defaultComponent>,
18
- ExternalComponentProps = React.ComponentProps<typeof defaultComponent>,
81
+ /**
82
+ * The children to render for the link. If no children are provided, the
83
+ * link's `text` property will be used.
84
+ */
85
+ children?: ReactNode;
86
+ } & (
87
+ | {
88
+ document: PrismicDocument | null | undefined;
89
+ href?: never;
90
+ field?: never;
91
+ }
92
+ | {
93
+ field: LinkField | null | undefined;
94
+ href?: never;
95
+ document?: never;
96
+ }
97
+ | {
98
+ href: LinkProps["href"];
99
+ field?: LinkField | null | undefined;
100
+ document?: never;
101
+ }
102
+ );
103
+
104
+ export const PrismicLink = forwardRef(function PrismicLink<
105
+ InternalComponentProps = ComponentProps<typeof defaultComponent>,
106
+ ExternalComponentProps = ComponentProps<typeof defaultComponent>,
19
107
  >(
20
108
  props: PrismicLinkProps<InternalComponentProps, ExternalComponentProps>,
21
- ref: React.ForwardedRef<Element>,
109
+ ref: ForwardedRef<Element>,
22
110
  ) {
23
- const context = usePrismicContext();
111
+ const {
112
+ field,
113
+ document: doc,
114
+ linkResolver,
115
+ internalComponent,
116
+ externalComponent,
117
+ children,
118
+ ...restProps
119
+ } = props;
120
+
121
+ if (DEV) {
122
+ if (field) {
123
+ if (!field.link_type) {
124
+ console.error(
125
+ `[PrismicLink] This "field" prop value caused an error to be thrown.\n`,
126
+ field,
127
+ );
128
+ throw new Error(
129
+ `[PrismicLink] The provided field is missing required properties to properly render a link. The link will not render. For more details, see ${devMsg(
130
+ "missing-link-properties",
131
+ )}`,
132
+ );
133
+ } else if (
134
+ ("text" in field
135
+ ? Object.keys(field).length > 2
136
+ : Object.keys(field).length > 1) &&
137
+ !("url" in field || "uid" in field || "id" in field)
138
+ ) {
139
+ console.warn(
140
+ `[PrismicLink] The provided field is missing required properties to properly render a link. The link may not render correctly. For more details, see ${devMsg(
141
+ "missing-link-properties",
142
+ )}`,
143
+ field,
144
+ );
145
+ }
146
+ } else if (doc) {
147
+ if (!("url" in doc || "id" in doc)) {
148
+ console.warn(
149
+ `[PrismicLink] The provided document is missing required properties to properly render a link. The link may not render correctly. For more details, see ${devMsg(
150
+ "missing-link-properties",
151
+ )}`,
152
+ doc,
153
+ );
154
+ }
155
+ }
156
+ }
157
+
158
+ const {
159
+ href: computedHref,
160
+ rel: computedRel,
161
+ ...attrs
162
+ } = asLinkAttrs(field ?? doc, {
163
+ linkResolver,
164
+ rel: typeof restProps.rel === "function" ? restProps.rel : undefined,
165
+ });
166
+
167
+ let rel: string | undefined = computedRel;
168
+ if ("rel" in restProps && typeof restProps.rel !== "function") {
169
+ rel = restProps.rel;
170
+ }
171
+
172
+ const href = ("href" in restProps ? restProps.href : computedHref) || "";
173
+
174
+ const InternalComponent = (internalComponent ||
175
+ defaultComponent) as ComponentType<LinkProps>;
176
+ const ExternalComponent = (externalComponent ||
177
+ defaultComponent) as ComponentType<LinkProps>;
178
+ const Component = href
179
+ ? isInternalURL(href)
180
+ ? InternalComponent
181
+ : ExternalComponent
182
+ : InternalComponent;
24
183
 
25
184
  return (
26
- <ServerPrismicLink
27
- ref={ref}
28
- linkResolver={context.linkResolver}
29
- internalComponent={context.internalLinkComponent}
30
- externalComponent={context.externalLinkComponent}
31
- {...props}
32
- />
185
+ <Component ref={ref} {...attrs} {...restProps} href={href} rel={rel}>
186
+ {"children" in props ? children : field?.text}
187
+ </Component>
33
188
  );
34
189
  }) as <
35
- InternalComponentProps = React.ComponentProps<typeof defaultComponent>,
36
- ExternalComponentProps = React.ComponentProps<typeof defaultComponent>,
190
+ InternalComponentProps = ComponentProps<typeof defaultComponent>,
191
+ ExternalComponentProps = ComponentProps<typeof defaultComponent>,
37
192
  >(
38
193
  props: PrismicLinkProps<InternalComponentProps, ExternalComponentProps> & {
39
- ref?: React.ForwardedRef<Element>;
194
+ ref?: ForwardedRef<Element>;
40
195
  },
41
- ) => React.JSX.Element;
196
+ ) => ReactNode;
197
+
198
+ /**
199
+ * Determines if a URL is internal or external.
200
+ *
201
+ * @param url - The URL to check if internal or external.
202
+ *
203
+ * @returns `true` if `url` is internal, `false` otherwise.
204
+ */
205
+ // TODO: This does not detect all relative URLs as internal such as `about` or `./about`. This function assumes relative URLs start with a "/" or "#"`.
206
+ export function isInternalURL(url: string): boolean {
207
+ const isInternal = /^(\/(?!\/)|#)/.test(url);
208
+ const isSpecialLink = !isInternal && !/^https?:\/\//.test(url);
209
+
210
+ return isInternal && !isSpecialLink;
211
+ }