polen 0.10.0-next.10 → 0.10.0-next.12

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 (328) hide show
  1. package/build/api/builder/builder.js +1 -1
  2. package/build/api/builder/builder.js.map +1 -1
  3. package/build/api/config/load.js +1 -1
  4. package/build/api/config/load.js.map +1 -1
  5. package/build/api/vite/plugins/build.js +1 -1
  6. package/build/api/vite/plugins/build.js.map +1 -1
  7. package/build/api/vite/plugins/core.d.ts.map +1 -1
  8. package/build/api/vite/plugins/core.js +0 -2
  9. package/build/api/vite/plugins/core.js.map +1 -1
  10. package/build/api/vite/plugins/pages.js +1 -1
  11. package/build/api/vite/plugins/pages.js.map +1 -1
  12. package/build/exports/components.d.ts +4 -1
  13. package/build/exports/components.d.ts.map +1 -1
  14. package/build/exports/components.js +4 -1
  15. package/build/exports/components.js.map +1 -1
  16. package/build/lib/demos/config-schema.d.ts +6 -6
  17. package/build/lib/github-actions/runner.js +2 -2
  18. package/build/lib/github-actions/runner.js.map +1 -1
  19. package/build/lib/graphql-document/$$.d.ts +5 -0
  20. package/build/lib/graphql-document/$$.d.ts.map +1 -0
  21. package/build/lib/graphql-document/$$.js +5 -0
  22. package/build/lib/graphql-document/$$.js.map +1 -0
  23. package/build/lib/graphql-document/$.d.ts +2 -0
  24. package/build/lib/graphql-document/$.d.ts.map +1 -0
  25. package/build/lib/graphql-document/$.js +2 -0
  26. package/build/lib/graphql-document/$.js.map +1 -0
  27. package/build/lib/graphql-document/analysis.d.ts +44 -0
  28. package/build/lib/graphql-document/analysis.d.ts.map +1 -0
  29. package/build/lib/graphql-document/analysis.js +361 -0
  30. package/build/lib/graphql-document/analysis.js.map +1 -0
  31. package/build/lib/graphql-document/components/GraphQLDocument.d.ts +42 -0
  32. package/build/lib/graphql-document/components/GraphQLDocument.d.ts.map +1 -0
  33. package/build/lib/graphql-document/components/GraphQLDocument.js +173 -0
  34. package/build/lib/graphql-document/components/GraphQLDocument.js.map +1 -0
  35. package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.d.ts +7 -0
  36. package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.d.ts.map +1 -0
  37. package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.js +45 -0
  38. package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.js.map +1 -0
  39. package/build/lib/graphql-document/components/HoverTooltip.d.ts +35 -0
  40. package/build/lib/graphql-document/components/HoverTooltip.d.ts.map +1 -0
  41. package/build/lib/graphql-document/components/HoverTooltip.js +132 -0
  42. package/build/lib/graphql-document/components/HoverTooltip.js.map +1 -0
  43. package/build/lib/graphql-document/components/IdentifierLink.d.ts +37 -0
  44. package/build/lib/graphql-document/components/IdentifierLink.d.ts.map +1 -0
  45. package/build/lib/graphql-document/components/IdentifierLink.js +141 -0
  46. package/build/lib/graphql-document/components/IdentifierLink.js.map +1 -0
  47. package/build/lib/graphql-document/components/index.d.ts +5 -0
  48. package/build/lib/graphql-document/components/index.d.ts.map +1 -0
  49. package/build/lib/graphql-document/components/index.js +5 -0
  50. package/build/lib/graphql-document/components/index.js.map +1 -0
  51. package/build/lib/graphql-document/example.d.ts +25 -0
  52. package/build/lib/graphql-document/example.d.ts.map +1 -0
  53. package/build/lib/graphql-document/example.js +140 -0
  54. package/build/lib/graphql-document/example.js.map +1 -0
  55. package/build/lib/graphql-document/graphql-document.d.ts +35 -0
  56. package/build/lib/graphql-document/graphql-document.d.ts.map +1 -0
  57. package/build/lib/graphql-document/graphql-document.js +36 -0
  58. package/build/lib/graphql-document/graphql-document.js.map +1 -0
  59. package/build/lib/graphql-document/positioning-simple.d.ts +68 -0
  60. package/build/lib/graphql-document/positioning-simple.d.ts.map +1 -0
  61. package/build/lib/graphql-document/positioning-simple.js +197 -0
  62. package/build/lib/graphql-document/positioning-simple.js.map +1 -0
  63. package/build/lib/graphql-document/schema-context.d.ts +8 -0
  64. package/build/lib/graphql-document/schema-context.d.ts.map +1 -0
  65. package/build/lib/graphql-document/schema-context.js +11 -0
  66. package/build/lib/graphql-document/schema-context.js.map +1 -0
  67. package/build/lib/graphql-document/schema-integration-example.d.ts +27 -0
  68. package/build/lib/graphql-document/schema-integration-example.d.ts.map +1 -0
  69. package/build/lib/graphql-document/schema-integration-example.js +297 -0
  70. package/build/lib/graphql-document/schema-integration-example.js.map +1 -0
  71. package/build/lib/graphql-document/schema-integration.d.ts +135 -0
  72. package/build/lib/graphql-document/schema-integration.d.ts.map +1 -0
  73. package/build/lib/graphql-document/schema-integration.js +328 -0
  74. package/build/lib/graphql-document/schema-integration.js.map +1 -0
  75. package/build/lib/graphql-document/types.d.ts +117 -0
  76. package/build/lib/graphql-document/types.d.ts.map +1 -0
  77. package/build/lib/graphql-document/types.js +2 -0
  78. package/build/lib/graphql-document/types.js.map +1 -0
  79. package/build/template/components/ArgumentAnnotation.js +10 -0
  80. package/build/template/components/ArgumentAnnotation.js.map +1 -0
  81. package/build/template/components/ArgumentList.js +9 -0
  82. package/build/template/components/ArgumentList.js.map +1 -0
  83. package/build/template/components/ArgumentListAnnotation.js +15 -0
  84. package/build/template/components/ArgumentListAnnotation.js.map +1 -0
  85. package/build/template/components/Changelog.js +44 -0
  86. package/build/template/components/Changelog.js.map +1 -0
  87. package/build/template/components/{CodeBlock.jsx → CodeBlock.js} +4 -5
  88. package/build/template/components/{CodeBlock.jsx.map → CodeBlock.js.map} +1 -1
  89. package/build/template/components/CodeBlockEnhancer.d.ts +2 -0
  90. package/build/template/components/CodeBlockEnhancer.d.ts.map +1 -0
  91. package/build/template/components/CodeBlockEnhancer.js +175 -0
  92. package/build/template/components/CodeBlockEnhancer.js.map +1 -0
  93. package/build/template/components/DeprecationReason.js +9 -0
  94. package/build/template/components/DeprecationReason.js.map +1 -0
  95. package/build/template/components/Description.js +9 -0
  96. package/build/template/components/Description.js.map +1 -0
  97. package/build/template/components/Field.js +14 -0
  98. package/build/template/components/Field.js.map +1 -0
  99. package/build/template/components/{FieldList.jsx → FieldList.js} +4 -5
  100. package/build/template/components/FieldList.js.map +1 -0
  101. package/build/template/components/{FieldListSection.jsx → FieldListSection.js} +4 -6
  102. package/build/template/components/FieldListSection.js.map +1 -0
  103. package/build/template/components/HamburgerMenu.js +30 -0
  104. package/build/template/components/HamburgerMenu.js.map +1 -0
  105. package/build/template/components/Link.d.ts +1 -1
  106. package/build/template/components/{Link.jsx → Link.js} +4 -5
  107. package/build/template/components/Link.js.map +1 -0
  108. package/build/template/components/Logo.js +20 -0
  109. package/build/template/components/Logo.js.map +1 -0
  110. package/build/template/components/MDXComponents.d.ts +11 -0
  111. package/build/template/components/MDXComponents.d.ts.map +1 -0
  112. package/build/template/components/MDXComponents.js +70 -0
  113. package/build/template/components/MDXComponents.js.map +1 -0
  114. package/build/template/components/{Markdown.jsx → Markdown.js} +3 -2
  115. package/build/template/components/Markdown.js.map +1 -0
  116. package/build/template/components/MissingSchema.d.ts +1 -1
  117. package/build/template/components/MissingSchema.d.ts.map +1 -1
  118. package/build/template/components/MissingSchema.js +5 -0
  119. package/build/template/components/MissingSchema.js.map +1 -0
  120. package/build/template/components/NamedType.js +12 -0
  121. package/build/template/components/NamedType.js.map +1 -0
  122. package/build/template/components/NotFound.js +7 -0
  123. package/build/template/components/NotFound.js.map +1 -0
  124. package/build/template/components/{RadixLink.jsx → RadixLink.js} +1 -1
  125. package/build/template/components/RadixLink.js.map +1 -0
  126. package/build/template/components/TestComponent.d.ts +5 -0
  127. package/build/template/components/TestComponent.d.ts.map +1 -0
  128. package/build/template/components/TestComponent.js +7 -0
  129. package/build/template/components/TestComponent.js.map +1 -0
  130. package/build/template/components/Texts/{MinorHeading.jsx → MinorHeading.js} +4 -3
  131. package/build/template/components/Texts/MinorHeading.js.map +1 -0
  132. package/build/template/components/Texts/texts.js +1 -1
  133. package/build/template/components/Texts/texts.js.map +1 -1
  134. package/build/template/components/ThemeToggle.js +9 -0
  135. package/build/template/components/ThemeToggle.js.map +1 -0
  136. package/build/template/components/{TypeAnnotation.jsx → TypeAnnotation.js} +8 -18
  137. package/build/template/components/TypeAnnotation.js.map +1 -0
  138. package/build/template/components/TypeFieldsLinkList.js +9 -0
  139. package/build/template/components/TypeFieldsLinkList.js.map +1 -0
  140. package/build/template/components/TypeIndex.js +17 -0
  141. package/build/template/components/TypeIndex.js.map +1 -0
  142. package/build/template/components/content/$$.d.ts +1 -0
  143. package/build/template/components/content/$$.d.ts.map +1 -1
  144. package/build/template/components/content/$$.js +1 -0
  145. package/build/template/components/content/$$.js.map +1 -1
  146. package/build/template/components/content/GraphQLDocumentWithSchema.d.ts +8 -0
  147. package/build/template/components/content/GraphQLDocumentWithSchema.d.ts.map +1 -0
  148. package/build/template/components/content/GraphQLDocumentWithSchema.js +16 -0
  149. package/build/template/components/content/GraphQLDocumentWithSchema.js.map +1 -0
  150. package/build/template/components/content/GraphQLDocumentWrapper.d.ts +7 -0
  151. package/build/template/components/content/GraphQLDocumentWrapper.d.ts.map +1 -0
  152. package/build/template/components/content/GraphQLDocumentWrapper.js +62 -0
  153. package/build/template/components/content/GraphQLDocumentWrapper.js.map +1 -0
  154. package/build/template/components/graphql/graphql.d.ts +2 -2
  155. package/build/template/components/graphql/graphql.js +3 -0
  156. package/build/template/components/graphql/graphql.js.map +1 -0
  157. package/build/template/components/graphql/index.d.ts +1 -1
  158. package/build/template/components/graphql/index.js +1 -1
  159. package/build/template/components/graphql/index.js.map +1 -1
  160. package/build/template/components/graphql/{type-kind-icon.jsx → type-kind-icon.js} +3 -2
  161. package/build/template/components/graphql/type-kind-icon.js.map +1 -0
  162. package/build/template/components/graphql/type-link.js +11 -0
  163. package/build/template/components/graphql/type-link.js.map +1 -0
  164. package/build/template/components/sidebar/Sidebar.d.ts +1 -1
  165. package/build/template/components/sidebar/Sidebar.d.ts.map +1 -1
  166. package/build/template/components/sidebar/Sidebar.js +11 -0
  167. package/build/template/components/sidebar/Sidebar.js.map +1 -0
  168. package/build/template/components/sidebar/{SidebarItem.jsx → SidebarItem.js} +15 -32
  169. package/build/template/components/sidebar/SidebarItem.js.map +1 -0
  170. package/build/template/components/sidebar/ToggleButton.d.ts +1 -1
  171. package/build/template/components/sidebar/ToggleButton.d.ts.map +1 -1
  172. package/build/template/components/sidebar/ToggleButton.js +5 -0
  173. package/build/template/components/sidebar/ToggleButton.js.map +1 -0
  174. package/build/template/contexts/{ThemeContext.jsx → ThemeContext.js} +3 -4
  175. package/build/template/contexts/{ThemeContext.jsx.map → ThemeContext.js.map} +1 -1
  176. package/build/template/entry.client.d.ts +1 -0
  177. package/build/template/entry.client.d.ts.map +1 -1
  178. package/build/template/{entry.client.jsx → entry.client.js} +5 -6
  179. package/build/template/entry.client.js.map +1 -0
  180. package/build/template/routes/changelog.d.ts +1 -1
  181. package/build/template/routes/{changelog.jsx → changelog.js} +5 -4
  182. package/build/template/routes/changelog.js.map +1 -0
  183. package/build/template/routes/{index.jsx → index.js} +3 -2
  184. package/build/template/routes/index.js.map +1 -0
  185. package/build/template/routes/reference.$type.$field.d.ts +1 -1
  186. package/build/template/routes/{reference.$type.$field.jsx → reference.$type.$field.js} +6 -5
  187. package/build/template/routes/reference.$type.$field.js.map +1 -0
  188. package/build/template/routes/reference.$type.d.ts +1 -1
  189. package/build/template/routes/{reference.$type.jsx → reference.$type.js} +6 -5
  190. package/build/template/routes/reference.$type.js.map +1 -0
  191. package/build/template/routes/reference.d.ts +2 -2
  192. package/build/template/routes/reference.d.ts.map +1 -1
  193. package/build/template/routes/{reference.jsx → reference.js} +7 -12
  194. package/build/template/routes/reference.js.map +1 -0
  195. package/build/template/routes/root.d.ts +2 -2
  196. package/build/template/routes/root.d.ts.map +1 -1
  197. package/build/template/routes/root.js +286 -0
  198. package/build/template/routes/root.js.map +1 -0
  199. package/build/template/routes.js +5 -0
  200. package/build/template/routes.js.map +1 -0
  201. package/build/template/server/app.js +1 -1
  202. package/build/template/server/app.js.map +1 -1
  203. package/build/template/server/{render-page.jsx → render-page.js} +3 -4
  204. package/build/template/server/render-page.js.map +1 -0
  205. package/build/template/server/ssg/generate.js +1 -1
  206. package/build/template/server/ssg/generate.js.map +1 -1
  207. package/build/template/server/ssg/get-route-paths.js +1 -1
  208. package/build/template/server/ssg/get-route-paths.js.map +1 -1
  209. package/build/template/server/view.js +1 -1
  210. package/build/template/server/view.js.map +1 -1
  211. package/package.json +56 -8
  212. package/src/api/vite/plugins/core.ts +0 -3
  213. package/src/api/vite/plugins/pages.ts +1 -1
  214. package/src/exports/components.ts +4 -1
  215. package/src/lib/graphql-document/$$.ts +4 -0
  216. package/src/lib/graphql-document/$.test.ts +132 -0
  217. package/src/lib/graphql-document/$.ts +1 -0
  218. package/src/lib/graphql-document/README.md +102 -0
  219. package/src/lib/graphql-document/analysis.ts +415 -0
  220. package/src/lib/graphql-document/components/GraphQLDocument.tsx +284 -0
  221. package/src/lib/graphql-document/components/GraphQLDocument.unit.test.ts +188 -0
  222. package/src/lib/graphql-document/components/GraphQLDocumentWithSchema.tsx +70 -0
  223. package/src/lib/graphql-document/components/HoverTooltip.tsx +282 -0
  224. package/src/lib/graphql-document/components/IdentifierLink.tsx +221 -0
  225. package/src/lib/graphql-document/components/index.ts +4 -0
  226. package/src/lib/graphql-document/demo.md +155 -0
  227. package/src/lib/graphql-document/example.ts +163 -0
  228. package/src/lib/graphql-document/graphql-document.ts +37 -0
  229. package/src/lib/graphql-document/positioning-simple.test.ts +252 -0
  230. package/src/lib/graphql-document/positioning-simple.ts +271 -0
  231. package/src/lib/graphql-document/schema-context.tsx +20 -0
  232. package/src/lib/graphql-document/schema-integration-example.ts +341 -0
  233. package/src/lib/graphql-document/schema-integration.test.ts +365 -0
  234. package/src/lib/graphql-document/schema-integration.ts +497 -0
  235. package/src/lib/graphql-document/types.ts +129 -0
  236. package/src/template/components/ArgumentAnnotation.tsx +1 -1
  237. package/src/template/components/ArgumentList.tsx +1 -1
  238. package/src/template/components/ArgumentListAnnotation.tsx +2 -2
  239. package/src/template/components/CodeBlockEnhancer.tsx +192 -0
  240. package/src/template/components/DeprecationReason.tsx +1 -1
  241. package/src/template/components/Description.tsx +1 -1
  242. package/src/template/components/Field.tsx +4 -4
  243. package/src/template/components/FieldList.tsx +1 -1
  244. package/src/template/components/FieldListSection.tsx +1 -1
  245. package/src/template/components/Link.tsx +2 -2
  246. package/src/template/components/MDXComponents.tsx +101 -0
  247. package/src/template/components/NamedType.tsx +2 -2
  248. package/src/template/components/TestComponent.tsx +6 -0
  249. package/src/template/components/TypeAnnotation.tsx +1 -1
  250. package/src/template/components/TypeFieldsLinkList.tsx +1 -1
  251. package/src/template/components/TypeIndex.tsx +1 -1
  252. package/src/template/components/content/$$.ts +1 -0
  253. package/src/template/components/content/GraphQLDocumentWithSchema.tsx +18 -0
  254. package/src/template/components/content/GraphQLDocumentWrapper.tsx +82 -0
  255. package/src/template/components/graphql/graphql.tsx +2 -2
  256. package/src/template/components/graphql/index.ts +1 -1
  257. package/src/template/components/graphql/type-link.tsx +2 -2
  258. package/src/template/components/sidebar/SidebarItem.tsx +4 -4
  259. package/src/template/entry.client.tsx +2 -2
  260. package/src/template/routes/changelog.tsx +1 -1
  261. package/src/template/routes/reference.$type.$field.tsx +3 -3
  262. package/src/template/routes/reference.$type.tsx +3 -3
  263. package/src/template/routes/reference.tsx +6 -10
  264. package/src/template/routes/root.tsx +145 -5
  265. package/src/template/routes.tsx +1 -1
  266. package/src/template/server/app.ts +1 -1
  267. package/src/template/server/ssg/generate.ts +1 -1
  268. package/src/template/server/ssg/get-route-paths.ts +1 -1
  269. package/src/template/server/view.ts +1 -1
  270. package/src/template/styles/code-block.css +32 -0
  271. package/build/template/components/ArgumentAnnotation.jsx +0 -16
  272. package/build/template/components/ArgumentAnnotation.jsx.map +0 -1
  273. package/build/template/components/ArgumentList.jsx +0 -16
  274. package/build/template/components/ArgumentList.jsx.map +0 -1
  275. package/build/template/components/ArgumentListAnnotation.jsx +0 -23
  276. package/build/template/components/ArgumentListAnnotation.jsx.map +0 -1
  277. package/build/template/components/Changelog.jsx +0 -68
  278. package/build/template/components/Changelog.jsx.map +0 -1
  279. package/build/template/components/DeprecationReason.jsx +0 -10
  280. package/build/template/components/DeprecationReason.jsx.map +0 -1
  281. package/build/template/components/Description.jsx +0 -10
  282. package/build/template/components/Description.jsx.map +0 -1
  283. package/build/template/components/Field.jsx +0 -22
  284. package/build/template/components/Field.jsx.map +0 -1
  285. package/build/template/components/FieldList.jsx.map +0 -1
  286. package/build/template/components/FieldListSection.jsx.map +0 -1
  287. package/build/template/components/HamburgerMenu.jsx +0 -53
  288. package/build/template/components/HamburgerMenu.jsx.map +0 -1
  289. package/build/template/components/Link.jsx.map +0 -1
  290. package/build/template/components/Logo.jsx +0 -29
  291. package/build/template/components/Logo.jsx.map +0 -1
  292. package/build/template/components/Markdown.jsx.map +0 -1
  293. package/build/template/components/MissingSchema.jsx +0 -4
  294. package/build/template/components/MissingSchema.jsx.map +0 -1
  295. package/build/template/components/NamedType.jsx +0 -17
  296. package/build/template/components/NamedType.jsx.map +0 -1
  297. package/build/template/components/NotFound.jsx +0 -26
  298. package/build/template/components/NotFound.jsx.map +0 -1
  299. package/build/template/components/RadixLink.jsx.map +0 -1
  300. package/build/template/components/Texts/MinorHeading.jsx.map +0 -1
  301. package/build/template/components/ThemeToggle.jsx +0 -10
  302. package/build/template/components/ThemeToggle.jsx.map +0 -1
  303. package/build/template/components/TypeAnnotation.jsx.map +0 -1
  304. package/build/template/components/TypeFieldsLinkList.jsx +0 -17
  305. package/build/template/components/TypeFieldsLinkList.jsx.map +0 -1
  306. package/build/template/components/TypeIndex.jsx +0 -27
  307. package/build/template/components/TypeIndex.jsx.map +0 -1
  308. package/build/template/components/graphql/graphql.jsx +0 -3
  309. package/build/template/components/graphql/graphql.jsx.map +0 -1
  310. package/build/template/components/graphql/type-kind-icon.jsx.map +0 -1
  311. package/build/template/components/graphql/type-link.jsx +0 -16
  312. package/build/template/components/graphql/type-link.jsx.map +0 -1
  313. package/build/template/components/sidebar/Sidebar.jsx +0 -15
  314. package/build/template/components/sidebar/Sidebar.jsx.map +0 -1
  315. package/build/template/components/sidebar/SidebarItem.jsx.map +0 -1
  316. package/build/template/components/sidebar/ToggleButton.jsx +0 -6
  317. package/build/template/components/sidebar/ToggleButton.jsx.map +0 -1
  318. package/build/template/entry.client.jsx.map +0 -1
  319. package/build/template/routes/changelog.jsx.map +0 -1
  320. package/build/template/routes/index.jsx.map +0 -1
  321. package/build/template/routes/reference.$type.$field.jsx.map +0 -1
  322. package/build/template/routes/reference.$type.jsx.map +0 -1
  323. package/build/template/routes/reference.jsx.map +0 -1
  324. package/build/template/routes/root.jsx +0 -204
  325. package/build/template/routes/root.jsx.map +0 -1
  326. package/build/template/routes.jsx +0 -5
  327. package/build/template/routes.jsx.map +0 -1
  328. package/build/template/server/render-page.jsx.map +0 -1
@@ -0,0 +1,252 @@
1
+ /**
2
+ * @vitest-environment jsdom
3
+ */
4
+
5
+ import { beforeEach, describe, expect, it } from 'vitest'
6
+ import { createSimpleOverlay, createSimplePositionCalculator } from './positioning-simple.ts'
7
+ import type { Identifier } from './types.ts'
8
+
9
+ // Helper to create test identifier
10
+ const createTestIdentifier = (
11
+ name: string,
12
+ line: number,
13
+ column: number,
14
+ kind: Identifier['kind'] = 'Field',
15
+ ): Identifier => ({
16
+ name,
17
+ kind,
18
+ position: {
19
+ start: column - 1,
20
+ end: column - 1 + name.length,
21
+ line,
22
+ column,
23
+ },
24
+ schemaPath: [name],
25
+ context: { selectionPath: [] },
26
+ })
27
+
28
+ describe('Simple Positioning Engine', () => {
29
+ describe('SimplePositionCalculator', () => {
30
+ const calculator = createSimplePositionCalculator()
31
+
32
+ it('should wrap identifiers in spans', () => {
33
+ const container = document.createElement('div')
34
+ container.innerHTML = `
35
+ <pre class="shiki">
36
+ <code>
37
+ <span class="line">query GetUser {</span>
38
+ <span class="line"> user {</span>
39
+ <span class="line"> name</span>
40
+ <span class="line"> }</span>
41
+ <span class="line">}</span>
42
+ </code>
43
+ </pre>
44
+ `
45
+
46
+ const identifiers = [
47
+ createTestIdentifier('query', 1, 1),
48
+ createTestIdentifier('user', 2, 3, 'Field'),
49
+ createTestIdentifier('name', 3, 5, 'Field'),
50
+ ]
51
+
52
+ calculator.prepareCodeBlock(container, identifiers)
53
+
54
+ // Check that identifiers were wrapped
55
+ const wrappedElements = container.querySelectorAll('[data-graphql-id]')
56
+ expect(wrappedElements.length).toBe(3)
57
+
58
+ // Check first wrapped element
59
+ const firstWrapped = wrappedElements[0] as HTMLElement
60
+ expect(firstWrapped.textContent).toBe('query')
61
+ expect(firstWrapped.getAttribute('data-graphql-name')).toBe('query')
62
+ expect(firstWrapped.getAttribute('data-graphql-kind')).toBe('Field')
63
+ })
64
+
65
+ it('should handle multiple identifiers in same line', () => {
66
+ const container = document.createElement('div')
67
+ container.innerHTML = `
68
+ <pre class="shiki">
69
+ <code>
70
+ <span class="line">query GetUserById($id: ID!) {</span>
71
+ </code>
72
+ </pre>
73
+ `
74
+
75
+ const identifiers = [
76
+ createTestIdentifier('query', 1, 1),
77
+ createTestIdentifier('GetUserById', 1, 7),
78
+ createTestIdentifier('$id', 1, 19, 'Variable'),
79
+ createTestIdentifier('ID', 1, 24, 'Type'),
80
+ ]
81
+
82
+ calculator.prepareCodeBlock(container, identifiers)
83
+
84
+ const wrappedElements = container.querySelectorAll('[data-graphql-id]')
85
+ expect(wrappedElements.length).toBe(4)
86
+ })
87
+
88
+ it('should get positions of wrapped identifiers', () => {
89
+ const container = document.createElement('div')
90
+ container.innerHTML = `
91
+ <pre class="shiki">
92
+ <code>
93
+ <span class="line"><span data-graphql-id="0-user-Field" data-graphql-name="user" data-graphql-kind="Field" data-graphql-start="0" data-graphql-end="4" data-graphql-line="1" data-graphql-column="1" data-graphql-path="user">user</span> {</span>
94
+ </code>
95
+ </pre>
96
+ `
97
+
98
+ // Mock getBoundingClientRect
99
+ container.getBoundingClientRect = () => ({
100
+ top: 0,
101
+ left: 0,
102
+ right: 100,
103
+ bottom: 100,
104
+ width: 100,
105
+ height: 100,
106
+ x: 0,
107
+ y: 0,
108
+ toJSON: () => ({}),
109
+ })
110
+
111
+ const userSpan = container.querySelector('[data-graphql-id]') as HTMLElement
112
+ userSpan.getBoundingClientRect = () => ({
113
+ top: 10,
114
+ left: 20,
115
+ right: 60,
116
+ bottom: 30,
117
+ width: 40,
118
+ height: 20,
119
+ x: 20,
120
+ y: 10,
121
+ toJSON: () => ({}),
122
+ })
123
+
124
+ const positions = calculator.getIdentifierPositions(container)
125
+
126
+ expect(positions.size).toBe(1)
127
+ const result = positions.get('0-user-Field')
128
+ expect(result).toBeDefined()
129
+ expect(result!.position).toEqual({
130
+ top: 10,
131
+ left: 20,
132
+ width: 40,
133
+ height: 20,
134
+ })
135
+ expect(result!.identifier.name).toBe('user')
136
+ expect(result!.identifier.kind).toBe('Field')
137
+ })
138
+
139
+ it('should skip already wrapped identifiers', () => {
140
+ const container = document.createElement('div')
141
+ container.innerHTML = `
142
+ <pre class="shiki">
143
+ <code>
144
+ <span class="line"><span data-graphql-id="existing">user</span> {</span>
145
+ </code>
146
+ </pre>
147
+ `
148
+
149
+ const identifiers = [
150
+ createTestIdentifier('user', 1, 1),
151
+ ]
152
+
153
+ calculator.prepareCodeBlock(container, identifiers)
154
+
155
+ // Should still only have one wrapped element
156
+ const wrappedElements = container.querySelectorAll('[data-graphql-id]')
157
+ expect(wrappedElements.length).toBe(1)
158
+ expect(wrappedElements[0]!.getAttribute('data-graphql-id')).toBe('existing')
159
+ })
160
+
161
+ it('should handle empty lines gracefully', () => {
162
+ const container = document.createElement('div')
163
+ container.innerHTML = `
164
+ <pre class="shiki">
165
+ <code>
166
+ <span class="line">query {</span>
167
+ <span class="line"></span>
168
+ <span class="line"> user</span>
169
+ </code>
170
+ </pre>
171
+ `
172
+
173
+ const identifiers = [
174
+ createTestIdentifier('query', 1, 1),
175
+ createTestIdentifier('user', 3, 3),
176
+ ]
177
+
178
+ expect(() => {
179
+ calculator.prepareCodeBlock(container, identifiers)
180
+ }).not.toThrow()
181
+
182
+ const wrappedElements = container.querySelectorAll('[data-graphql-id]')
183
+ expect(wrappedElements.length).toBe(2)
184
+ })
185
+ })
186
+
187
+ describe('createSimpleOverlay', () => {
188
+ it('should create positioned overlay element', () => {
189
+ const position = { top: 10, left: 20, width: 40, height: 20 }
190
+ const identifier = createTestIdentifier('user', 1, 1)
191
+
192
+ const overlay = createSimpleOverlay(position, identifier)
193
+
194
+ expect(overlay.style.position).toBe('absolute')
195
+ expect(overlay.style.top).toBe('10px')
196
+ expect(overlay.style.left).toBe('20px')
197
+ expect(overlay.style.width).toBe('40px')
198
+ expect(overlay.style.height).toBe('20px')
199
+ expect(overlay.style.cursor).toBe('pointer')
200
+ expect(overlay.getAttribute('data-graphql-overlay')).toBe('true')
201
+ expect(overlay.getAttribute('data-graphql-name')).toBe('user')
202
+ expect(overlay.getAttribute('data-graphql-kind')).toBe('Field')
203
+ })
204
+
205
+ it('should handle click events', () => {
206
+ const position = { top: 10, left: 20, width: 40, height: 20 }
207
+ const identifier = createTestIdentifier('user', 1, 1)
208
+ let clickedIdentifier: Identifier | null = null
209
+
210
+ const overlay = createSimpleOverlay(position, identifier, {
211
+ onClick: (id) => {
212
+ clickedIdentifier = id
213
+ },
214
+ })
215
+
216
+ // Simulate click
217
+ const event = new MouseEvent('click')
218
+ overlay.dispatchEvent(event)
219
+
220
+ expect(clickedIdentifier).toBe(identifier)
221
+ })
222
+
223
+ it('should handle hover events', () => {
224
+ const position = { top: 10, left: 20, width: 40, height: 20 }
225
+ const identifier = createTestIdentifier('user', 1, 1)
226
+ let hoveredIdentifier: Identifier | null = null
227
+
228
+ const overlay = createSimpleOverlay(position, identifier, {
229
+ onHover: (id) => {
230
+ hoveredIdentifier = id
231
+ },
232
+ })
233
+
234
+ // Simulate hover
235
+ const event = new MouseEvent('mouseenter')
236
+ overlay.dispatchEvent(event)
237
+
238
+ expect(hoveredIdentifier).toBe(identifier)
239
+ })
240
+
241
+ it('should apply custom className', () => {
242
+ const position = { top: 10, left: 20, width: 40, height: 20 }
243
+ const identifier = createTestIdentifier('user', 1, 1)
244
+
245
+ const overlay = createSimpleOverlay(position, identifier, {
246
+ className: 'custom-overlay-class',
247
+ })
248
+
249
+ expect(overlay.className).toBe('custom-overlay-class')
250
+ })
251
+ })
252
+ })
@@ -0,0 +1,271 @@
1
+ /**
2
+ * Layer 3: Simplified Positioning & Layout Engine
3
+ *
4
+ * Maps GraphQL AST positions to DOM coordinates for overlay placement.
5
+ * This simplified version focuses on working with Polen's existing infrastructure.
6
+ */
7
+
8
+ import type { Identifier } from './types.ts'
9
+
10
+ /**
11
+ * DOM position for rendering overlays
12
+ */
13
+ export interface DOMPosition {
14
+ /** Distance from top of container in pixels */
15
+ top: number
16
+ /** Distance from left of container in pixels */
17
+ left: number
18
+ /** Width of the identifier in pixels */
19
+ width: number
20
+ /** Height of the identifier in pixels */
21
+ height: number
22
+ }
23
+
24
+ /**
25
+ * Position calculation result
26
+ */
27
+ export interface PositionResult {
28
+ /** The calculated DOM position */
29
+ position: DOMPosition
30
+ /** The identifier this position is for */
31
+ identifier: Identifier
32
+ }
33
+
34
+ /**
35
+ * Simplified position calculator for Shiki-rendered code
36
+ *
37
+ * This version uses a more straightforward approach:
38
+ * 1. Find the line element by line number
39
+ * 2. Search for the identifier text within that line
40
+ * 3. Create a span around the identifier for positioning
41
+ *
42
+ * This approach modifies the DOM but is more reliable for testing
43
+ * and works well with React's reconciliation.
44
+ */
45
+ export class SimplePositionCalculator {
46
+ /**
47
+ * Prepare a code block for positioning by wrapping identifiers in spans
48
+ */
49
+ prepareCodeBlock(
50
+ containerElement: Element,
51
+ identifiers: Identifier[],
52
+ ): void {
53
+ // Sort all identifiers by position (right to left, bottom to top)
54
+ const sortedIdentifiers = [...identifiers].sort((a, b) => {
55
+ // Sort by line first (bottom to top)
56
+ if (a.position.line !== b.position.line) {
57
+ return b.position.line - a.position.line
58
+ }
59
+ // Then by column (right to left)
60
+ return b.position.column - a.position.column
61
+ })
62
+
63
+ // Process all identifiers
64
+ let wrappedCount = 0
65
+ for (const identifier of sortedIdentifiers) {
66
+ const wrapped = this.wrapIdentifier(containerElement, identifier)
67
+ if (wrapped) wrappedCount++
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Get positions of all wrapped identifiers
73
+ */
74
+ getIdentifierPositions(
75
+ containerElement: Element,
76
+ relativeToElement?: Element,
77
+ ): Map<string, PositionResult> {
78
+ const results = new Map<string, PositionResult>()
79
+
80
+ // Find all wrapped identifiers
81
+ const wrappedIdentifiers = containerElement.querySelectorAll('[data-graphql-id]')
82
+
83
+ // Use the provided element for relative positioning, or the container itself
84
+ const referenceElement = relativeToElement || containerElement
85
+
86
+ for (const element of wrappedIdentifiers) {
87
+ const id = element.getAttribute('data-graphql-id')
88
+ if (!id) continue
89
+
90
+ // Get position relative to the reference element
91
+ const referenceRect = referenceElement.getBoundingClientRect()
92
+ const elementRect = element.getBoundingClientRect()
93
+
94
+ const position: DOMPosition = {
95
+ top: elementRect.top - referenceRect.top,
96
+ left: elementRect.left - referenceRect.left,
97
+ width: elementRect.width,
98
+ height: elementRect.height,
99
+ }
100
+
101
+ // Reconstruct identifier from data attributes
102
+ const identifier: Identifier = {
103
+ name: element.getAttribute('data-graphql-name') || '',
104
+ kind: (element.getAttribute('data-graphql-kind') || 'Field') as Identifier['kind'],
105
+ position: {
106
+ start: parseInt(element.getAttribute('data-graphql-start') || '0'),
107
+ end: parseInt(element.getAttribute('data-graphql-end') || '0'),
108
+ line: parseInt(element.getAttribute('data-graphql-line') || '1'),
109
+ column: parseInt(element.getAttribute('data-graphql-column') || '1'),
110
+ },
111
+ schemaPath: (element.getAttribute('data-graphql-path') || '').split(',').filter(Boolean),
112
+ context: { selectionPath: [] },
113
+ }
114
+
115
+ results.set(id, { position, identifier })
116
+ }
117
+
118
+ return results
119
+ }
120
+
121
+ /**
122
+ * Wrap an identifier in a span for positioning
123
+ * Returns true if the identifier was successfully wrapped
124
+ */
125
+ private wrapIdentifier(containerElement: Element, identifier: Identifier): boolean {
126
+ const walker = document.createTreeWalker(
127
+ containerElement,
128
+ NodeFilter.SHOW_TEXT,
129
+ null,
130
+ )
131
+
132
+ let currentLine = 1
133
+ let currentColumn = 1
134
+ let node: Node | null
135
+
136
+ while (node = walker.nextNode()) {
137
+ const textNode = node as Text
138
+ const text = textNode.textContent || ''
139
+
140
+ // Check if already wrapped
141
+ if (textNode.parentElement?.hasAttribute('data-graphql-id')) {
142
+ // Update position tracking and continue
143
+ for (const char of text) {
144
+ if (char === '\n') {
145
+ currentLine++
146
+ currentColumn = 1
147
+ } else {
148
+ currentColumn++
149
+ }
150
+ }
151
+ continue
152
+ }
153
+
154
+ // Track position in the text
155
+ let textIndex = 0
156
+ while (textIndex < text.length) {
157
+ // Check if we're at the identifier's position
158
+ if (
159
+ currentLine === identifier.position.line
160
+ && currentColumn === identifier.position.column
161
+ ) {
162
+ // Verify it's actually our identifier
163
+ const remainingText = text.substring(textIndex)
164
+ if (remainingText.startsWith(identifier.name)) {
165
+ // Create a unique ID for this identifier
166
+ const id = `${identifier.position.start}-${identifier.name}-${identifier.kind}`
167
+
168
+ // Split the text node and wrap the identifier
169
+ const before = text.substring(0, textIndex)
170
+ const after = text.substring(textIndex + identifier.name.length)
171
+
172
+ const span = document.createElement('span')
173
+ span.setAttribute('data-graphql-id', id)
174
+ span.setAttribute('data-graphql-name', identifier.name)
175
+ span.setAttribute('data-graphql-kind', identifier.kind)
176
+ span.setAttribute('data-graphql-start', String(identifier.position.start))
177
+ span.setAttribute('data-graphql-end', String(identifier.position.end))
178
+ span.setAttribute('data-graphql-line', String(identifier.position.line))
179
+ span.setAttribute('data-graphql-column', String(identifier.position.column))
180
+ span.setAttribute('data-graphql-path', identifier.schemaPath.join(','))
181
+ span.textContent = identifier.name
182
+
183
+ const parent = textNode.parentNode!
184
+
185
+ if (before) {
186
+ parent.insertBefore(document.createTextNode(before), textNode)
187
+ }
188
+
189
+ parent.insertBefore(span, textNode)
190
+
191
+ if (after) {
192
+ parent.insertBefore(document.createTextNode(after), textNode)
193
+ }
194
+
195
+ parent.removeChild(textNode)
196
+ return true
197
+ }
198
+ }
199
+
200
+ // Update position tracking
201
+ const char = text[textIndex]
202
+ if (char === '\n') {
203
+ currentLine++
204
+ currentColumn = 1
205
+ } else {
206
+ currentColumn++
207
+ }
208
+ textIndex++
209
+ }
210
+ }
211
+
212
+ return false // Identifier not found
213
+ }
214
+ }
215
+
216
+ /**
217
+ * Create invisible overlay for a position
218
+ */
219
+ export const createSimpleOverlay = (
220
+ position: DOMPosition,
221
+ identifier: Identifier,
222
+ options?: {
223
+ onClick?: (identifier: Identifier) => void
224
+ onHover?: (identifier: Identifier, event: MouseEvent) => void
225
+ className?: string
226
+ },
227
+ ): HTMLElement => {
228
+ const overlay = document.createElement('div')
229
+
230
+ // Base styles for positioning
231
+ overlay.style.position = 'absolute'
232
+ overlay.style.top = `${position.top}px`
233
+ overlay.style.left = `${position.left}px`
234
+ overlay.style.width = `${position.width}px`
235
+ overlay.style.height = `${position.height}px`
236
+ overlay.style.cursor = 'pointer'
237
+ overlay.style.zIndex = '10'
238
+
239
+ // Add custom class if provided
240
+ if (options?.className) {
241
+ overlay.className = options.className
242
+ }
243
+
244
+ // Data attributes
245
+ overlay.setAttribute('data-graphql-overlay', 'true')
246
+ overlay.setAttribute('data-graphql-name', identifier.name)
247
+ overlay.setAttribute('data-graphql-kind', identifier.kind)
248
+
249
+ // Event handlers
250
+ if (options?.onClick) {
251
+ overlay.addEventListener('click', (e) => {
252
+ e.preventDefault()
253
+ options.onClick!(identifier)
254
+ })
255
+ }
256
+
257
+ if (options?.onHover) {
258
+ overlay.addEventListener('mouseenter', (e) => {
259
+ options.onHover!(identifier, e)
260
+ })
261
+ }
262
+
263
+ return overlay
264
+ }
265
+
266
+ /**
267
+ * Factory function for position calculator
268
+ */
269
+ export const createSimplePositionCalculator = (): SimplePositionCalculator => {
270
+ return new SimplePositionCalculator()
271
+ }
@@ -0,0 +1,20 @@
1
+ import type { GraphQLSchema } from 'graphql'
2
+ import React from 'react'
3
+
4
+ export const GraphQLSchemaContext = React.createContext<GraphQLSchema | null>(null)
5
+
6
+ export const useGraphQLSchema = () => {
7
+ const schema = React.useContext(GraphQLSchemaContext)
8
+ return schema
9
+ }
10
+
11
+ export const GraphQLSchemaProvider: React.FC<React.PropsWithChildren<{ schema: GraphQLSchema | null }>> = ({
12
+ children,
13
+ schema,
14
+ }) => {
15
+ return (
16
+ <GraphQLSchemaContext.Provider value={schema}>
17
+ {children}
18
+ </GraphQLSchemaContext.Provider>
19
+ )
20
+ }