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.
- package/build/api/builder/builder.js +1 -1
- package/build/api/builder/builder.js.map +1 -1
- package/build/api/config/load.js +1 -1
- package/build/api/config/load.js.map +1 -1
- package/build/api/vite/plugins/build.js +1 -1
- package/build/api/vite/plugins/build.js.map +1 -1
- package/build/api/vite/plugins/core.d.ts.map +1 -1
- package/build/api/vite/plugins/core.js +0 -2
- package/build/api/vite/plugins/core.js.map +1 -1
- package/build/api/vite/plugins/pages.js +1 -1
- package/build/api/vite/plugins/pages.js.map +1 -1
- package/build/exports/components.d.ts +4 -1
- package/build/exports/components.d.ts.map +1 -1
- package/build/exports/components.js +4 -1
- package/build/exports/components.js.map +1 -1
- package/build/lib/demos/config-schema.d.ts +6 -6
- package/build/lib/github-actions/runner.js +2 -2
- package/build/lib/github-actions/runner.js.map +1 -1
- package/build/lib/graphql-document/$$.d.ts +5 -0
- package/build/lib/graphql-document/$$.d.ts.map +1 -0
- package/build/lib/graphql-document/$$.js +5 -0
- package/build/lib/graphql-document/$$.js.map +1 -0
- package/build/lib/graphql-document/$.d.ts +2 -0
- package/build/lib/graphql-document/$.d.ts.map +1 -0
- package/build/lib/graphql-document/$.js +2 -0
- package/build/lib/graphql-document/$.js.map +1 -0
- package/build/lib/graphql-document/analysis.d.ts +44 -0
- package/build/lib/graphql-document/analysis.d.ts.map +1 -0
- package/build/lib/graphql-document/analysis.js +361 -0
- package/build/lib/graphql-document/analysis.js.map +1 -0
- package/build/lib/graphql-document/components/GraphQLDocument.d.ts +42 -0
- package/build/lib/graphql-document/components/GraphQLDocument.d.ts.map +1 -0
- package/build/lib/graphql-document/components/GraphQLDocument.js +173 -0
- package/build/lib/graphql-document/components/GraphQLDocument.js.map +1 -0
- package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.d.ts +7 -0
- package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.d.ts.map +1 -0
- package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.js +45 -0
- package/build/lib/graphql-document/components/GraphQLDocumentWithSchema.js.map +1 -0
- package/build/lib/graphql-document/components/HoverTooltip.d.ts +35 -0
- package/build/lib/graphql-document/components/HoverTooltip.d.ts.map +1 -0
- package/build/lib/graphql-document/components/HoverTooltip.js +132 -0
- package/build/lib/graphql-document/components/HoverTooltip.js.map +1 -0
- package/build/lib/graphql-document/components/IdentifierLink.d.ts +37 -0
- package/build/lib/graphql-document/components/IdentifierLink.d.ts.map +1 -0
- package/build/lib/graphql-document/components/IdentifierLink.js +141 -0
- package/build/lib/graphql-document/components/IdentifierLink.js.map +1 -0
- package/build/lib/graphql-document/components/index.d.ts +5 -0
- package/build/lib/graphql-document/components/index.d.ts.map +1 -0
- package/build/lib/graphql-document/components/index.js +5 -0
- package/build/lib/graphql-document/components/index.js.map +1 -0
- package/build/lib/graphql-document/example.d.ts +25 -0
- package/build/lib/graphql-document/example.d.ts.map +1 -0
- package/build/lib/graphql-document/example.js +140 -0
- package/build/lib/graphql-document/example.js.map +1 -0
- package/build/lib/graphql-document/graphql-document.d.ts +35 -0
- package/build/lib/graphql-document/graphql-document.d.ts.map +1 -0
- package/build/lib/graphql-document/graphql-document.js +36 -0
- package/build/lib/graphql-document/graphql-document.js.map +1 -0
- package/build/lib/graphql-document/positioning-simple.d.ts +68 -0
- package/build/lib/graphql-document/positioning-simple.d.ts.map +1 -0
- package/build/lib/graphql-document/positioning-simple.js +197 -0
- package/build/lib/graphql-document/positioning-simple.js.map +1 -0
- package/build/lib/graphql-document/schema-context.d.ts +8 -0
- package/build/lib/graphql-document/schema-context.d.ts.map +1 -0
- package/build/lib/graphql-document/schema-context.js +11 -0
- package/build/lib/graphql-document/schema-context.js.map +1 -0
- package/build/lib/graphql-document/schema-integration-example.d.ts +27 -0
- package/build/lib/graphql-document/schema-integration-example.d.ts.map +1 -0
- package/build/lib/graphql-document/schema-integration-example.js +297 -0
- package/build/lib/graphql-document/schema-integration-example.js.map +1 -0
- package/build/lib/graphql-document/schema-integration.d.ts +135 -0
- package/build/lib/graphql-document/schema-integration.d.ts.map +1 -0
- package/build/lib/graphql-document/schema-integration.js +328 -0
- package/build/lib/graphql-document/schema-integration.js.map +1 -0
- package/build/lib/graphql-document/types.d.ts +117 -0
- package/build/lib/graphql-document/types.d.ts.map +1 -0
- package/build/lib/graphql-document/types.js +2 -0
- package/build/lib/graphql-document/types.js.map +1 -0
- package/build/template/components/ArgumentAnnotation.js +10 -0
- package/build/template/components/ArgumentAnnotation.js.map +1 -0
- package/build/template/components/ArgumentList.js +9 -0
- package/build/template/components/ArgumentList.js.map +1 -0
- package/build/template/components/ArgumentListAnnotation.js +15 -0
- package/build/template/components/ArgumentListAnnotation.js.map +1 -0
- package/build/template/components/Changelog.js +44 -0
- package/build/template/components/Changelog.js.map +1 -0
- package/build/template/components/{CodeBlock.jsx → CodeBlock.js} +4 -5
- package/build/template/components/{CodeBlock.jsx.map → CodeBlock.js.map} +1 -1
- package/build/template/components/CodeBlockEnhancer.d.ts +2 -0
- package/build/template/components/CodeBlockEnhancer.d.ts.map +1 -0
- package/build/template/components/CodeBlockEnhancer.js +175 -0
- package/build/template/components/CodeBlockEnhancer.js.map +1 -0
- package/build/template/components/DeprecationReason.js +9 -0
- package/build/template/components/DeprecationReason.js.map +1 -0
- package/build/template/components/Description.js +9 -0
- package/build/template/components/Description.js.map +1 -0
- package/build/template/components/Field.js +14 -0
- package/build/template/components/Field.js.map +1 -0
- package/build/template/components/{FieldList.jsx → FieldList.js} +4 -5
- package/build/template/components/FieldList.js.map +1 -0
- package/build/template/components/{FieldListSection.jsx → FieldListSection.js} +4 -6
- package/build/template/components/FieldListSection.js.map +1 -0
- package/build/template/components/HamburgerMenu.js +30 -0
- package/build/template/components/HamburgerMenu.js.map +1 -0
- package/build/template/components/Link.d.ts +1 -1
- package/build/template/components/{Link.jsx → Link.js} +4 -5
- package/build/template/components/Link.js.map +1 -0
- package/build/template/components/Logo.js +20 -0
- package/build/template/components/Logo.js.map +1 -0
- package/build/template/components/MDXComponents.d.ts +11 -0
- package/build/template/components/MDXComponents.d.ts.map +1 -0
- package/build/template/components/MDXComponents.js +70 -0
- package/build/template/components/MDXComponents.js.map +1 -0
- package/build/template/components/{Markdown.jsx → Markdown.js} +3 -2
- package/build/template/components/Markdown.js.map +1 -0
- package/build/template/components/MissingSchema.d.ts +1 -1
- package/build/template/components/MissingSchema.d.ts.map +1 -1
- package/build/template/components/MissingSchema.js +5 -0
- package/build/template/components/MissingSchema.js.map +1 -0
- package/build/template/components/NamedType.js +12 -0
- package/build/template/components/NamedType.js.map +1 -0
- package/build/template/components/NotFound.js +7 -0
- package/build/template/components/NotFound.js.map +1 -0
- package/build/template/components/{RadixLink.jsx → RadixLink.js} +1 -1
- package/build/template/components/RadixLink.js.map +1 -0
- package/build/template/components/TestComponent.d.ts +5 -0
- package/build/template/components/TestComponent.d.ts.map +1 -0
- package/build/template/components/TestComponent.js +7 -0
- package/build/template/components/TestComponent.js.map +1 -0
- package/build/template/components/Texts/{MinorHeading.jsx → MinorHeading.js} +4 -3
- package/build/template/components/Texts/MinorHeading.js.map +1 -0
- package/build/template/components/Texts/texts.js +1 -1
- package/build/template/components/Texts/texts.js.map +1 -1
- package/build/template/components/ThemeToggle.js +9 -0
- package/build/template/components/ThemeToggle.js.map +1 -0
- package/build/template/components/{TypeAnnotation.jsx → TypeAnnotation.js} +8 -18
- package/build/template/components/TypeAnnotation.js.map +1 -0
- package/build/template/components/TypeFieldsLinkList.js +9 -0
- package/build/template/components/TypeFieldsLinkList.js.map +1 -0
- package/build/template/components/TypeIndex.js +17 -0
- package/build/template/components/TypeIndex.js.map +1 -0
- package/build/template/components/content/$$.d.ts +1 -0
- package/build/template/components/content/$$.d.ts.map +1 -1
- package/build/template/components/content/$$.js +1 -0
- package/build/template/components/content/$$.js.map +1 -1
- package/build/template/components/content/GraphQLDocumentWithSchema.d.ts +8 -0
- package/build/template/components/content/GraphQLDocumentWithSchema.d.ts.map +1 -0
- package/build/template/components/content/GraphQLDocumentWithSchema.js +16 -0
- package/build/template/components/content/GraphQLDocumentWithSchema.js.map +1 -0
- package/build/template/components/content/GraphQLDocumentWrapper.d.ts +7 -0
- package/build/template/components/content/GraphQLDocumentWrapper.d.ts.map +1 -0
- package/build/template/components/content/GraphQLDocumentWrapper.js +62 -0
- package/build/template/components/content/GraphQLDocumentWrapper.js.map +1 -0
- package/build/template/components/graphql/graphql.d.ts +2 -2
- package/build/template/components/graphql/graphql.js +3 -0
- package/build/template/components/graphql/graphql.js.map +1 -0
- package/build/template/components/graphql/index.d.ts +1 -1
- package/build/template/components/graphql/index.js +1 -1
- package/build/template/components/graphql/index.js.map +1 -1
- package/build/template/components/graphql/{type-kind-icon.jsx → type-kind-icon.js} +3 -2
- package/build/template/components/graphql/type-kind-icon.js.map +1 -0
- package/build/template/components/graphql/type-link.js +11 -0
- package/build/template/components/graphql/type-link.js.map +1 -0
- package/build/template/components/sidebar/Sidebar.d.ts +1 -1
- package/build/template/components/sidebar/Sidebar.d.ts.map +1 -1
- package/build/template/components/sidebar/Sidebar.js +11 -0
- package/build/template/components/sidebar/Sidebar.js.map +1 -0
- package/build/template/components/sidebar/{SidebarItem.jsx → SidebarItem.js} +15 -32
- package/build/template/components/sidebar/SidebarItem.js.map +1 -0
- package/build/template/components/sidebar/ToggleButton.d.ts +1 -1
- package/build/template/components/sidebar/ToggleButton.d.ts.map +1 -1
- package/build/template/components/sidebar/ToggleButton.js +5 -0
- package/build/template/components/sidebar/ToggleButton.js.map +1 -0
- package/build/template/contexts/{ThemeContext.jsx → ThemeContext.js} +3 -4
- package/build/template/contexts/{ThemeContext.jsx.map → ThemeContext.js.map} +1 -1
- package/build/template/entry.client.d.ts +1 -0
- package/build/template/entry.client.d.ts.map +1 -1
- package/build/template/{entry.client.jsx → entry.client.js} +5 -6
- package/build/template/entry.client.js.map +1 -0
- package/build/template/routes/changelog.d.ts +1 -1
- package/build/template/routes/{changelog.jsx → changelog.js} +5 -4
- package/build/template/routes/changelog.js.map +1 -0
- package/build/template/routes/{index.jsx → index.js} +3 -2
- package/build/template/routes/index.js.map +1 -0
- package/build/template/routes/reference.$type.$field.d.ts +1 -1
- package/build/template/routes/{reference.$type.$field.jsx → reference.$type.$field.js} +6 -5
- package/build/template/routes/reference.$type.$field.js.map +1 -0
- package/build/template/routes/reference.$type.d.ts +1 -1
- package/build/template/routes/{reference.$type.jsx → reference.$type.js} +6 -5
- package/build/template/routes/reference.$type.js.map +1 -0
- package/build/template/routes/reference.d.ts +2 -2
- package/build/template/routes/reference.d.ts.map +1 -1
- package/build/template/routes/{reference.jsx → reference.js} +7 -12
- package/build/template/routes/reference.js.map +1 -0
- package/build/template/routes/root.d.ts +2 -2
- package/build/template/routes/root.d.ts.map +1 -1
- package/build/template/routes/root.js +286 -0
- package/build/template/routes/root.js.map +1 -0
- package/build/template/routes.js +5 -0
- package/build/template/routes.js.map +1 -0
- package/build/template/server/app.js +1 -1
- package/build/template/server/app.js.map +1 -1
- package/build/template/server/{render-page.jsx → render-page.js} +3 -4
- package/build/template/server/render-page.js.map +1 -0
- package/build/template/server/ssg/generate.js +1 -1
- package/build/template/server/ssg/generate.js.map +1 -1
- package/build/template/server/ssg/get-route-paths.js +1 -1
- package/build/template/server/ssg/get-route-paths.js.map +1 -1
- package/build/template/server/view.js +1 -1
- package/build/template/server/view.js.map +1 -1
- package/package.json +56 -8
- package/src/api/vite/plugins/core.ts +0 -3
- package/src/api/vite/plugins/pages.ts +1 -1
- package/src/exports/components.ts +4 -1
- package/src/lib/graphql-document/$$.ts +4 -0
- package/src/lib/graphql-document/$.test.ts +132 -0
- package/src/lib/graphql-document/$.ts +1 -0
- package/src/lib/graphql-document/README.md +102 -0
- package/src/lib/graphql-document/analysis.ts +415 -0
- package/src/lib/graphql-document/components/GraphQLDocument.tsx +284 -0
- package/src/lib/graphql-document/components/GraphQLDocument.unit.test.ts +188 -0
- package/src/lib/graphql-document/components/GraphQLDocumentWithSchema.tsx +70 -0
- package/src/lib/graphql-document/components/HoverTooltip.tsx +282 -0
- package/src/lib/graphql-document/components/IdentifierLink.tsx +221 -0
- package/src/lib/graphql-document/components/index.ts +4 -0
- package/src/lib/graphql-document/demo.md +155 -0
- package/src/lib/graphql-document/example.ts +163 -0
- package/src/lib/graphql-document/graphql-document.ts +37 -0
- package/src/lib/graphql-document/positioning-simple.test.ts +252 -0
- package/src/lib/graphql-document/positioning-simple.ts +271 -0
- package/src/lib/graphql-document/schema-context.tsx +20 -0
- package/src/lib/graphql-document/schema-integration-example.ts +341 -0
- package/src/lib/graphql-document/schema-integration.test.ts +365 -0
- package/src/lib/graphql-document/schema-integration.ts +497 -0
- package/src/lib/graphql-document/types.ts +129 -0
- package/src/template/components/ArgumentAnnotation.tsx +1 -1
- package/src/template/components/ArgumentList.tsx +1 -1
- package/src/template/components/ArgumentListAnnotation.tsx +2 -2
- package/src/template/components/CodeBlockEnhancer.tsx +192 -0
- package/src/template/components/DeprecationReason.tsx +1 -1
- package/src/template/components/Description.tsx +1 -1
- package/src/template/components/Field.tsx +4 -4
- package/src/template/components/FieldList.tsx +1 -1
- package/src/template/components/FieldListSection.tsx +1 -1
- package/src/template/components/Link.tsx +2 -2
- package/src/template/components/MDXComponents.tsx +101 -0
- package/src/template/components/NamedType.tsx +2 -2
- package/src/template/components/TestComponent.tsx +6 -0
- package/src/template/components/TypeAnnotation.tsx +1 -1
- package/src/template/components/TypeFieldsLinkList.tsx +1 -1
- package/src/template/components/TypeIndex.tsx +1 -1
- package/src/template/components/content/$$.ts +1 -0
- package/src/template/components/content/GraphQLDocumentWithSchema.tsx +18 -0
- package/src/template/components/content/GraphQLDocumentWrapper.tsx +82 -0
- package/src/template/components/graphql/graphql.tsx +2 -2
- package/src/template/components/graphql/index.ts +1 -1
- package/src/template/components/graphql/type-link.tsx +2 -2
- package/src/template/components/sidebar/SidebarItem.tsx +4 -4
- package/src/template/entry.client.tsx +2 -2
- package/src/template/routes/changelog.tsx +1 -1
- package/src/template/routes/reference.$type.$field.tsx +3 -3
- package/src/template/routes/reference.$type.tsx +3 -3
- package/src/template/routes/reference.tsx +6 -10
- package/src/template/routes/root.tsx +145 -5
- package/src/template/routes.tsx +1 -1
- package/src/template/server/app.ts +1 -1
- package/src/template/server/ssg/generate.ts +1 -1
- package/src/template/server/ssg/get-route-paths.ts +1 -1
- package/src/template/server/view.ts +1 -1
- package/src/template/styles/code-block.css +32 -0
- package/build/template/components/ArgumentAnnotation.jsx +0 -16
- package/build/template/components/ArgumentAnnotation.jsx.map +0 -1
- package/build/template/components/ArgumentList.jsx +0 -16
- package/build/template/components/ArgumentList.jsx.map +0 -1
- package/build/template/components/ArgumentListAnnotation.jsx +0 -23
- package/build/template/components/ArgumentListAnnotation.jsx.map +0 -1
- package/build/template/components/Changelog.jsx +0 -68
- package/build/template/components/Changelog.jsx.map +0 -1
- package/build/template/components/DeprecationReason.jsx +0 -10
- package/build/template/components/DeprecationReason.jsx.map +0 -1
- package/build/template/components/Description.jsx +0 -10
- package/build/template/components/Description.jsx.map +0 -1
- package/build/template/components/Field.jsx +0 -22
- package/build/template/components/Field.jsx.map +0 -1
- package/build/template/components/FieldList.jsx.map +0 -1
- package/build/template/components/FieldListSection.jsx.map +0 -1
- package/build/template/components/HamburgerMenu.jsx +0 -53
- package/build/template/components/HamburgerMenu.jsx.map +0 -1
- package/build/template/components/Link.jsx.map +0 -1
- package/build/template/components/Logo.jsx +0 -29
- package/build/template/components/Logo.jsx.map +0 -1
- package/build/template/components/Markdown.jsx.map +0 -1
- package/build/template/components/MissingSchema.jsx +0 -4
- package/build/template/components/MissingSchema.jsx.map +0 -1
- package/build/template/components/NamedType.jsx +0 -17
- package/build/template/components/NamedType.jsx.map +0 -1
- package/build/template/components/NotFound.jsx +0 -26
- package/build/template/components/NotFound.jsx.map +0 -1
- package/build/template/components/RadixLink.jsx.map +0 -1
- package/build/template/components/Texts/MinorHeading.jsx.map +0 -1
- package/build/template/components/ThemeToggle.jsx +0 -10
- package/build/template/components/ThemeToggle.jsx.map +0 -1
- package/build/template/components/TypeAnnotation.jsx.map +0 -1
- package/build/template/components/TypeFieldsLinkList.jsx +0 -17
- package/build/template/components/TypeFieldsLinkList.jsx.map +0 -1
- package/build/template/components/TypeIndex.jsx +0 -27
- package/build/template/components/TypeIndex.jsx.map +0 -1
- package/build/template/components/graphql/graphql.jsx +0 -3
- package/build/template/components/graphql/graphql.jsx.map +0 -1
- package/build/template/components/graphql/type-kind-icon.jsx.map +0 -1
- package/build/template/components/graphql/type-link.jsx +0 -16
- package/build/template/components/graphql/type-link.jsx.map +0 -1
- package/build/template/components/sidebar/Sidebar.jsx +0 -15
- package/build/template/components/sidebar/Sidebar.jsx.map +0 -1
- package/build/template/components/sidebar/SidebarItem.jsx.map +0 -1
- package/build/template/components/sidebar/ToggleButton.jsx +0 -6
- package/build/template/components/sidebar/ToggleButton.jsx.map +0 -1
- package/build/template/entry.client.jsx.map +0 -1
- package/build/template/routes/changelog.jsx.map +0 -1
- package/build/template/routes/index.jsx.map +0 -1
- package/build/template/routes/reference.$type.$field.jsx.map +0 -1
- package/build/template/routes/reference.$type.jsx.map +0 -1
- package/build/template/routes/reference.jsx.map +0 -1
- package/build/template/routes/root.jsx +0 -204
- package/build/template/routes/root.jsx.map +0 -1
- package/build/template/routes.jsx +0 -5
- package/build/template/routes.jsx.map +0 -1
- 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
|
+
}
|