polen 0.10.0-next.12 → 0.10.0-next.13

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 (42) hide show
  1. package/build/lib/graphql-document/components/CopyButton.d.ts +19 -0
  2. package/build/lib/graphql-document/components/CopyButton.d.ts.map +1 -0
  3. package/build/lib/graphql-document/components/CopyButton.js +43 -0
  4. package/build/lib/graphql-document/components/CopyButton.js.map +1 -0
  5. package/build/lib/graphql-document/components/GraphQLDocument.d.ts +0 -4
  6. package/build/lib/graphql-document/components/GraphQLDocument.d.ts.map +1 -1
  7. package/build/lib/graphql-document/components/GraphQLDocument.js +31 -74
  8. package/build/lib/graphql-document/components/GraphQLDocument.js.map +1 -1
  9. package/build/lib/graphql-document/components/GraphQLIdentifierPopover.d.ts +33 -0
  10. package/build/lib/graphql-document/components/GraphQLIdentifierPopover.d.ts.map +1 -0
  11. package/build/lib/graphql-document/components/GraphQLIdentifierPopover.js +48 -0
  12. package/build/lib/graphql-document/components/GraphQLIdentifierPopover.js.map +1 -0
  13. package/build/lib/graphql-document/components/IdentifierLink.d.ts +15 -13
  14. package/build/lib/graphql-document/components/IdentifierLink.d.ts.map +1 -1
  15. package/build/lib/graphql-document/components/IdentifierLink.js +51 -117
  16. package/build/lib/graphql-document/components/IdentifierLink.js.map +1 -1
  17. package/build/lib/graphql-document/components/graphql-document-styles.d.ts +5 -0
  18. package/build/lib/graphql-document/components/graphql-document-styles.d.ts.map +1 -0
  19. package/build/lib/graphql-document/components/graphql-document-styles.js +167 -0
  20. package/build/lib/graphql-document/components/graphql-document-styles.js.map +1 -0
  21. package/build/lib/graphql-document/components/index.d.ts +2 -1
  22. package/build/lib/graphql-document/components/index.d.ts.map +1 -1
  23. package/build/lib/graphql-document/components/index.js +2 -1
  24. package/build/lib/graphql-document/components/index.js.map +1 -1
  25. package/build/lib/graphql-document/hooks/use-tooltip-state.d.ts +43 -0
  26. package/build/lib/graphql-document/hooks/use-tooltip-state.d.ts.map +1 -0
  27. package/build/lib/graphql-document/hooks/use-tooltip-state.js +132 -0
  28. package/build/lib/graphql-document/hooks/use-tooltip-state.js.map +1 -0
  29. package/package.json +2 -1
  30. package/src/lib/graphql-document/components/CopyButton.tsx +76 -0
  31. package/src/lib/graphql-document/components/GraphQLDocument.tsx +52 -86
  32. package/src/lib/graphql-document/components/GraphQLIdentifierPopover.tsx +197 -0
  33. package/src/lib/graphql-document/components/IdentifierLink.tsx +105 -166
  34. package/src/lib/graphql-document/components/graphql-document-styles.ts +167 -0
  35. package/src/lib/graphql-document/components/index.ts +2 -1
  36. package/src/lib/graphql-document/hooks/use-tooltip-state.test.ts +76 -0
  37. package/src/lib/graphql-document/hooks/use-tooltip-state.ts +191 -0
  38. package/build/lib/graphql-document/components/HoverTooltip.d.ts +0 -35
  39. package/build/lib/graphql-document/components/HoverTooltip.d.ts.map +0 -1
  40. package/build/lib/graphql-document/components/HoverTooltip.js +0 -132
  41. package/build/lib/graphql-document/components/HoverTooltip.js.map +0 -1
  42. package/src/lib/graphql-document/components/HoverTooltip.tsx +0 -282
@@ -0,0 +1,191 @@
1
+ /**
2
+ * State management for GraphQL document tooltips
3
+ *
4
+ * Handles hover delays, pinning, and multiple tooltip coordination
5
+ */
6
+
7
+ import { React } from '#dep/react/index'
8
+
9
+ export interface TooltipState {
10
+ /** Currently visible tooltip (via hover) */
11
+ hoveredId: string | null
12
+ /** Set of pinned tooltip IDs */
13
+ pinnedIds: Set<string>
14
+ /** ID pending show (waiting for delay) */
15
+ pendingShowId: string | null
16
+ /** ID pending hide (waiting for grace period) */
17
+ pendingHideId: string | null
18
+ }
19
+
20
+ export interface UseTooltipStateOptions {
21
+ /** Delay before showing tooltip on hover (ms) */
22
+ showDelay?: number
23
+ /** Delay before hiding tooltip on mouse leave (ms) */
24
+ hideDelay?: number
25
+ /** Whether to allow multiple pinned tooltips */
26
+ allowMultiplePins?: boolean
27
+ }
28
+
29
+ export interface UseTooltipStateReturn {
30
+ /** Check if a tooltip should be visible */
31
+ isOpen: (id: string) => boolean
32
+ /** Check if a tooltip is pinned */
33
+ isPinned: (id: string) => boolean
34
+ /** Handle hover start */
35
+ onHoverStart: (id: string) => void
36
+ /** Handle hover end */
37
+ onHoverEnd: (id: string) => void
38
+ /** Handle click (toggle pin) */
39
+ onTogglePin: (id: string) => void
40
+ /** Handle tooltip content hover (cancels hide) */
41
+ onTooltipHover: (id: string) => void
42
+ /** Unpin a specific tooltip */
43
+ unpin: (id: string) => void
44
+ /** Unpin all tooltips */
45
+ unpinAll: () => void
46
+ }
47
+
48
+ export const useTooltipState = (options: UseTooltipStateOptions = {}): UseTooltipStateReturn => {
49
+ const {
50
+ showDelay = 300,
51
+ hideDelay = 200,
52
+ allowMultiplePins = true,
53
+ } = options
54
+
55
+ const [hoveredId, setHoveredId] = React.useState<string | null>(null)
56
+ const [pinnedIds, setPinnedIds] = React.useState<Set<string>>(new Set())
57
+ const [pendingShowId, setPendingShowId] = React.useState<string | null>(null)
58
+ const [pendingHideId, setPendingHideId] = React.useState<string | null>(null)
59
+
60
+ // Timer refs
61
+ const showTimerRef = React.useRef<NodeJS.Timeout | null>(null)
62
+ const hideTimerRef = React.useRef<NodeJS.Timeout | null>(null)
63
+
64
+ // Clear any pending timers
65
+ const clearTimers = React.useCallback(() => {
66
+ if (showTimerRef.current) {
67
+ clearTimeout(showTimerRef.current)
68
+ showTimerRef.current = null
69
+ }
70
+ if (hideTimerRef.current) {
71
+ clearTimeout(hideTimerRef.current)
72
+ hideTimerRef.current = null
73
+ }
74
+ setPendingShowId(null)
75
+ setPendingHideId(null)
76
+ }, [])
77
+
78
+ // Check if tooltip should be visible
79
+ const isOpen = React.useCallback((id: string): boolean => {
80
+ return hoveredId === id || pinnedIds.has(id)
81
+ }, [hoveredId, pinnedIds])
82
+
83
+ // Check if tooltip is pinned
84
+ const isPinned = React.useCallback((id: string): boolean => {
85
+ return pinnedIds.has(id)
86
+ }, [pinnedIds])
87
+
88
+ // Handle hover start
89
+ const onHoverStart = React.useCallback((id: string) => {
90
+ // Don't show if already pinned
91
+ if (pinnedIds.has(id)) return
92
+
93
+ // Cancel any pending hide for this ID
94
+ if (pendingHideId === id) {
95
+ clearTimeout(hideTimerRef.current!)
96
+ hideTimerRef.current = null
97
+ setPendingHideId(null)
98
+ return
99
+ }
100
+
101
+ // Clear any other pending operations
102
+ clearTimers()
103
+
104
+ // Schedule show
105
+ setPendingShowId(id)
106
+ showTimerRef.current = setTimeout(() => {
107
+ setHoveredId(id)
108
+ setPendingShowId(null)
109
+ }, showDelay)
110
+ }, [pinnedIds, pendingHideId, clearTimers, showDelay])
111
+
112
+ // Handle hover end
113
+ const onHoverEnd = React.useCallback((id: string) => {
114
+ // Don't hide if pinned
115
+ if (pinnedIds.has(id)) return
116
+
117
+ // Cancel pending show if still waiting
118
+ if (pendingShowId === id) {
119
+ clearTimeout(showTimerRef.current!)
120
+ showTimerRef.current = null
121
+ setPendingShowId(null)
122
+ return
123
+ }
124
+
125
+ // Only hide if currently showing this tooltip
126
+ if (hoveredId === id) {
127
+ setPendingHideId(id)
128
+ hideTimerRef.current = setTimeout(() => {
129
+ // First set hovered to null to trigger close animation
130
+ setHoveredId(null)
131
+ setPendingHideId(null)
132
+ }, hideDelay)
133
+ }
134
+ }, [pinnedIds, pendingShowId, hoveredId, hideDelay])
135
+
136
+ // Handle tooltip content hover (cancels hide)
137
+ const onTooltipHover = React.useCallback((id: string) => {
138
+ if (pendingHideId === id) {
139
+ clearTimeout(hideTimerRef.current!)
140
+ hideTimerRef.current = null
141
+ setPendingHideId(null)
142
+ }
143
+ }, [pendingHideId])
144
+
145
+ // Toggle pin state
146
+ const onTogglePin = React.useCallback((id: string) => {
147
+ clearTimers()
148
+
149
+ setPinnedIds((prev: Set<string>) => {
150
+ const next = new Set(prev)
151
+ if (next.has(id)) {
152
+ // Unpin
153
+ next.delete(id)
154
+ setHoveredId(null) // Also clear hover state
155
+ } else {
156
+ // Pin
157
+ if (!allowMultiplePins) {
158
+ next.clear() // Clear other pins
159
+ }
160
+ next.add(id)
161
+ setHoveredId(null) // Clear hover state since it's now pinned
162
+ }
163
+ return next
164
+ })
165
+ }, [clearTimers, allowMultiplePins])
166
+
167
+ // Unpin specific tooltip
168
+ const unpin = React.useCallback((id: string) => {
169
+ setPinnedIds((prev: Set<string>) => {
170
+ const next = new Set(prev)
171
+ next.delete(id)
172
+ return next
173
+ })
174
+ }, [])
175
+
176
+ // Unpin all tooltips
177
+ const unpinAll = React.useCallback(() => {
178
+ setPinnedIds(new Set())
179
+ }, [])
180
+
181
+ return {
182
+ isOpen,
183
+ isPinned,
184
+ onHoverStart,
185
+ onHoverEnd,
186
+ onTogglePin,
187
+ onTooltipHover,
188
+ unpin,
189
+ unpinAll,
190
+ }
191
+ }
@@ -1,35 +0,0 @@
1
- import type { React } from '#dep/react/index';
2
- import type { DOMPosition } from '../positioning-simple.ts';
3
- import type { Documentation } from '../schema-integration.ts';
4
- import type { Identifier } from '../types.ts';
5
- /**
6
- * Props for the HoverTooltip component
7
- */
8
- export interface HoverTooltipProps {
9
- /** The identifier being hovered */
10
- identifier: Identifier;
11
- /** Documentation from schema */
12
- documentation: Documentation;
13
- /** Position of the identifier */
14
- position: DOMPosition;
15
- /** Whether this identifier has an error */
16
- hasError?: boolean;
17
- /** Reference URL for "View docs" link */
18
- referenceUrl: string;
19
- /** Callback to close the tooltip */
20
- onClose?: () => void;
21
- /** Callback to navigate to docs */
22
- onNavigate?: () => void;
23
- }
24
- /**
25
- * Tooltip shown on hover over GraphQL identifiers
26
- *
27
- * Displays type information, descriptions, deprecation warnings,
28
- * and links to full documentation.
29
- */
30
- export declare const HoverTooltip: React.FC<HoverTooltipProps>;
31
- /**
32
- * Default styles for hover tooltips
33
- */
34
- export declare const hoverTooltipStyles = "\n.graphql-hover-tooltip {\n /* Tooltip animation */\n animation: graphql-tooltip-fade-in 0.2s ease-out;\n}\n\n@keyframes graphql-tooltip-fade-in {\n from {\n opacity: 0;\n transform: translateY(4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Ensure tooltips appear above other content */\n.graphql-hover-tooltip .rt-Card {\n box-shadow: 0 10px 38px -10px rgba(22, 23, 24, 0.35), \n 0 10px 20px -15px rgba(22, 23, 24, 0.2);\n}\n";
35
- //# sourceMappingURL=HoverTooltip.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HoverTooltip.d.ts","sourceRoot":"","sources":["../../../../src/lib/graphql-document/components/HoverTooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAG7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,UAAU,EAAE,UAAU,CAAA;IACtB,gCAAgC;IAChC,aAAa,EAAE,aAAa,CAAA;IAC5B,iCAAiC;IACjC,QAAQ,EAAE,WAAW,CAAA;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAA;IACpB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,mCAAmC;IACnC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;CACxB;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA6NpD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,yeAsB9B,CAAA"}
@@ -1,132 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Badge, Box, Card, Flex, Text } from '@radix-ui/themes';
3
- import { useEffect, useRef, useState } from 'react';
4
- /**
5
- * Tooltip shown on hover over GraphQL identifiers
6
- *
7
- * Displays type information, descriptions, deprecation warnings,
8
- * and links to full documentation.
9
- */
10
- export const HoverTooltip = ({ identifier, documentation, position, hasError = false, referenceUrl, onClose, onNavigate, }) => {
11
- const tooltipRef = useRef(null);
12
- const [tooltipPosition, setTooltipPosition] = useState({ top: 0, left: 0 });
13
- // Calculate tooltip position to avoid viewport edges
14
- useEffect(() => {
15
- if (!tooltipRef.current)
16
- return;
17
- const tooltip = tooltipRef.current;
18
- const rect = tooltip.getBoundingClientRect();
19
- const viewportWidth = window.innerWidth;
20
- const viewportHeight = window.innerHeight;
21
- // Default position: above the identifier
22
- let top = position.top - rect.height - 8;
23
- let left = position.left;
24
- // Adjust if tooltip would go off screen
25
- if (top < 0) {
26
- // Show below if not enough space above
27
- top = position.top + position.height + 8;
28
- }
29
- if (left + rect.width > viewportWidth) {
30
- // Align right edge with identifier if too wide
31
- left = position.left + position.width - rect.width;
32
- }
33
- if (left < 0) {
34
- // Keep on screen
35
- left = 8;
36
- }
37
- setTooltipPosition({ top, left });
38
- }, [position]);
39
- // Determine badge color based on identifier kind
40
- const getBadgeColor = () => {
41
- switch (identifier.kind) {
42
- case 'Type':
43
- return 'blue';
44
- case 'Field':
45
- return 'green';
46
- case 'Argument':
47
- return 'orange';
48
- case 'Variable':
49
- return 'purple';
50
- case 'Directive':
51
- return 'amber';
52
- case 'Fragment':
53
- return 'cyan';
54
- default:
55
- return 'gray';
56
- }
57
- };
58
- return (_jsx("div", { ref: tooltipRef, className: 'graphql-hover-tooltip', style: {
59
- position: 'absolute',
60
- top: tooltipPosition.top,
61
- left: tooltipPosition.left,
62
- zIndex: 100,
63
- maxWidth: '400px',
64
- pointerEvents: 'auto', // Make tooltip interactive
65
- }, children: _jsx(Card, { size: '2', variant: 'surface', children: _jsxs(Flex, { direction: 'column', gap: '2', children: [_jsxs(Flex, { justify: 'between', align: 'center', children: [_jsxs(Flex, { align: 'center', gap: '2', children: [_jsx(Text, { size: '2', weight: 'bold', children: identifier.name }), _jsx(Badge, { color: getBadgeColor(), size: '1', children: identifier.kind })] }), onClose && (_jsx("button", { onClick: onClose, style: {
66
- background: 'none',
67
- border: 'none',
68
- cursor: 'pointer',
69
- padding: '4px',
70
- color: 'var(--gray-11)',
71
- fontSize: '18px',
72
- lineHeight: '1',
73
- fontWeight: 'bold',
74
- borderRadius: '4px',
75
- transition: 'background-color 0.2s',
76
- }, onMouseEnter: (e) => {
77
- e.currentTarget.style.backgroundColor = 'var(--gray-a3)';
78
- }, onMouseLeave: (e) => {
79
- e.currentTarget.style.backgroundColor = 'transparent';
80
- }, "aria-label": 'Close tooltip', children: "\u00D7" }))] }), _jsx(Box, { children: _jsxs(Text, { size: '1', color: 'gray', children: ["Type: ", _jsx(Text, { as: 'span', size: '1', style: { fontFamily: 'monospace' }, children: documentation.typeInfo })] }) }), documentation.description && (_jsx(Box, { children: _jsx(Text, { size: '1', children: documentation.description }) })), documentation.defaultValue && (_jsx(Box, { children: _jsxs(Text, { size: '1', color: 'gray', children: ["Default:", ' ', _jsx(Text, { as: 'span', size: '1', style: { fontFamily: 'monospace' }, children: documentation.defaultValue })] }) })), documentation.deprecated && (_jsxs(Box, { style: {
81
- padding: '8px',
82
- backgroundColor: 'var(--amber-2)',
83
- borderRadius: '4px',
84
- border: '1px solid var(--amber-6)',
85
- }, children: [_jsxs(Text, { size: '1', color: 'amber', children: ["\u26A0\uFE0F Deprecated: ", documentation.deprecated.reason] }), documentation.deprecated.replacement && (_jsxs(Text, { size: '1', color: 'amber', children: ["Use ", documentation.deprecated.replacement, " instead."] }))] })), hasError && (_jsx(Box, { style: {
86
- padding: '8px',
87
- backgroundColor: 'var(--red-2)',
88
- borderRadius: '4px',
89
- border: '1px solid var(--red-6)',
90
- }, children: _jsxs(Text, { size: '1', color: 'red', children: ["\u274C ", identifier.kind, " not found in schema"] }) })), _jsx(Box, { children: _jsxs(Text, { size: '1', color: 'gray', children: ["Path: ", identifier.schemaPath.join(' → ')] }) }), onNavigate && (_jsx(Box, { children: _jsx(Text, { size: '1', children: _jsx("a", { href: referenceUrl, onClick: (e) => {
91
- e.preventDefault();
92
- onNavigate();
93
- onClose?.();
94
- }, style: {
95
- color: 'var(--accent-9)',
96
- textDecoration: 'none',
97
- borderBottom: '1px solid transparent',
98
- transition: 'border-color 0.2s',
99
- cursor: 'pointer',
100
- }, onMouseEnter: (e) => {
101
- e.currentTarget.style.borderBottomColor = 'var(--accent-9)';
102
- }, onMouseLeave: (e) => {
103
- e.currentTarget.style.borderBottomColor = 'transparent';
104
- }, children: "View full documentation \u2192" }) }) }))] }) }) }));
105
- };
106
- /**
107
- * Default styles for hover tooltips
108
- */
109
- export const hoverTooltipStyles = `
110
- .graphql-hover-tooltip {
111
- /* Tooltip animation */
112
- animation: graphql-tooltip-fade-in 0.2s ease-out;
113
- }
114
-
115
- @keyframes graphql-tooltip-fade-in {
116
- from {
117
- opacity: 0;
118
- transform: translateY(4px);
119
- }
120
- to {
121
- opacity: 1;
122
- transform: translateY(0);
123
- }
124
- }
125
-
126
- /* Ensure tooltips appear above other content */
127
- .graphql-hover-tooltip .rt-Card {
128
- box-shadow: 0 10px 38px -10px rgba(22, 23, 24, 0.35),
129
- 0 10px 20px -15px rgba(22, 23, 24, 0.2);
130
- }
131
- `;
132
- //# sourceMappingURL=HoverTooltip.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HoverTooltip.js","sourceRoot":"","sources":["../../../../src/lib/graphql-document/components/HoverTooltip.tsx"],"names":[],"mappings":"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"}
@@ -1,282 +0,0 @@
1
- import type { React } from '#dep/react/index'
2
- import { Badge, Box, Card, Flex, Text } from '@radix-ui/themes'
3
- import { useEffect, useRef, useState } from 'react'
4
- import type { DOMPosition } from '../positioning-simple.ts'
5
- import type { Documentation } from '../schema-integration.ts'
6
- import type { Identifier } from '../types.ts'
7
-
8
- /**
9
- * Props for the HoverTooltip component
10
- */
11
- export interface HoverTooltipProps {
12
- /** The identifier being hovered */
13
- identifier: Identifier
14
- /** Documentation from schema */
15
- documentation: Documentation
16
- /** Position of the identifier */
17
- position: DOMPosition
18
- /** Whether this identifier has an error */
19
- hasError?: boolean
20
- /** Reference URL for "View docs" link */
21
- referenceUrl: string
22
- /** Callback to close the tooltip */
23
- onClose?: () => void
24
- /** Callback to navigate to docs */
25
- onNavigate?: () => void
26
- }
27
-
28
- /**
29
- * Tooltip shown on hover over GraphQL identifiers
30
- *
31
- * Displays type information, descriptions, deprecation warnings,
32
- * and links to full documentation.
33
- */
34
- export const HoverTooltip: React.FC<HoverTooltipProps> = ({
35
- identifier,
36
- documentation,
37
- position,
38
- hasError = false,
39
- referenceUrl,
40
- onClose,
41
- onNavigate,
42
- }) => {
43
- const tooltipRef = useRef<HTMLDivElement>(null)
44
- const [tooltipPosition, setTooltipPosition] = useState({ top: 0, left: 0 })
45
-
46
- // Calculate tooltip position to avoid viewport edges
47
- useEffect(() => {
48
- if (!tooltipRef.current) return
49
-
50
- const tooltip = tooltipRef.current
51
- const rect = tooltip.getBoundingClientRect()
52
- const viewportWidth = window.innerWidth
53
- const viewportHeight = window.innerHeight
54
-
55
- // Default position: above the identifier
56
- let top = position.top - rect.height - 8
57
- let left = position.left
58
-
59
- // Adjust if tooltip would go off screen
60
- if (top < 0) {
61
- // Show below if not enough space above
62
- top = position.top + position.height + 8
63
- }
64
-
65
- if (left + rect.width > viewportWidth) {
66
- // Align right edge with identifier if too wide
67
- left = position.left + position.width - rect.width
68
- }
69
-
70
- if (left < 0) {
71
- // Keep on screen
72
- left = 8
73
- }
74
-
75
- setTooltipPosition({ top, left })
76
- }, [position])
77
-
78
- // Determine badge color based on identifier kind
79
- const getBadgeColor = () => {
80
- switch (identifier.kind) {
81
- case 'Type':
82
- return 'blue'
83
- case 'Field':
84
- return 'green'
85
- case 'Argument':
86
- return 'orange'
87
- case 'Variable':
88
- return 'purple'
89
- case 'Directive':
90
- return 'amber'
91
- case 'Fragment':
92
- return 'cyan'
93
- default:
94
- return 'gray'
95
- }
96
- }
97
-
98
- return (
99
- <div
100
- ref={tooltipRef}
101
- className='graphql-hover-tooltip'
102
- style={{
103
- position: 'absolute',
104
- top: tooltipPosition.top,
105
- left: tooltipPosition.left,
106
- zIndex: 100,
107
- maxWidth: '400px',
108
- pointerEvents: 'auto', // Make tooltip interactive
109
- }}
110
- >
111
- <Card size='2' variant='surface'>
112
- <Flex direction='column' gap='2'>
113
- {/* Header with name, kind, and close button */}
114
- <Flex justify='between' align='center'>
115
- <Flex align='center' gap='2'>
116
- <Text size='2' weight='bold'>
117
- {identifier.name}
118
- </Text>
119
- <Badge color={getBadgeColor()} size='1'>
120
- {identifier.kind}
121
- </Badge>
122
- </Flex>
123
- {onClose && (
124
- <button
125
- onClick={onClose}
126
- style={{
127
- background: 'none',
128
- border: 'none',
129
- cursor: 'pointer',
130
- padding: '4px',
131
- color: 'var(--gray-11)',
132
- fontSize: '18px',
133
- lineHeight: '1',
134
- fontWeight: 'bold',
135
- borderRadius: '4px',
136
- transition: 'background-color 0.2s',
137
- }}
138
- onMouseEnter={(e) => {
139
- e.currentTarget.style.backgroundColor = 'var(--gray-a3)'
140
- }}
141
- onMouseLeave={(e) => {
142
- e.currentTarget.style.backgroundColor = 'transparent'
143
- }}
144
- aria-label='Close tooltip'
145
- >
146
- ×
147
- </button>
148
- )}
149
- </Flex>
150
-
151
- {/* Type signature */}
152
- <Box>
153
- <Text size='1' color='gray'>
154
- Type: <Text as='span' size='1' style={{ fontFamily: 'monospace' }}>{documentation.typeInfo}</Text>
155
- </Text>
156
- </Box>
157
-
158
- {/* Description */}
159
- {documentation.description && (
160
- <Box>
161
- <Text size='1'>
162
- {documentation.description}
163
- </Text>
164
- </Box>
165
- )}
166
-
167
- {/* Default value for arguments */}
168
- {documentation.defaultValue && (
169
- <Box>
170
- <Text size='1' color='gray'>
171
- Default:{' '}
172
- <Text as='span' size='1' style={{ fontFamily: 'monospace' }}>{documentation.defaultValue}</Text>
173
- </Text>
174
- </Box>
175
- )}
176
-
177
- {/* Deprecation warning */}
178
- {documentation.deprecated && (
179
- <Box
180
- style={{
181
- padding: '8px',
182
- backgroundColor: 'var(--amber-2)',
183
- borderRadius: '4px',
184
- border: '1px solid var(--amber-6)',
185
- }}
186
- >
187
- <Text size='1' color='amber'>
188
- ⚠️ Deprecated: {documentation.deprecated.reason}
189
- </Text>
190
- {documentation.deprecated.replacement && (
191
- <Text size='1' color='amber'>
192
- Use {documentation.deprecated.replacement} instead.
193
- </Text>
194
- )}
195
- </Box>
196
- )}
197
-
198
- {/* Error message */}
199
- {hasError && (
200
- <Box
201
- style={{
202
- padding: '8px',
203
- backgroundColor: 'var(--red-2)',
204
- borderRadius: '4px',
205
- border: '1px solid var(--red-6)',
206
- }}
207
- >
208
- <Text size='1' color='red'>
209
- ❌ {identifier.kind} not found in schema
210
- </Text>
211
- </Box>
212
- )}
213
-
214
- {/* Schema path */}
215
- <Box>
216
- <Text size='1' color='gray'>
217
- Path: {identifier.schemaPath.join(' → ')}
218
- </Text>
219
- </Box>
220
-
221
- {/* View docs link */}
222
- {onNavigate && (
223
- <Box>
224
- <Text size='1'>
225
- <a
226
- href={referenceUrl}
227
- onClick={(e) => {
228
- e.preventDefault()
229
- onNavigate()
230
- onClose?.()
231
- }}
232
- style={{
233
- color: 'var(--accent-9)',
234
- textDecoration: 'none',
235
- borderBottom: '1px solid transparent',
236
- transition: 'border-color 0.2s',
237
- cursor: 'pointer',
238
- }}
239
- onMouseEnter={(e) => {
240
- e.currentTarget.style.borderBottomColor = 'var(--accent-9)'
241
- }}
242
- onMouseLeave={(e) => {
243
- e.currentTarget.style.borderBottomColor = 'transparent'
244
- }}
245
- >
246
- View full documentation →
247
- </a>
248
- </Text>
249
- </Box>
250
- )}
251
- </Flex>
252
- </Card>
253
- </div>
254
- )
255
- }
256
-
257
- /**
258
- * Default styles for hover tooltips
259
- */
260
- export const hoverTooltipStyles = `
261
- .graphql-hover-tooltip {
262
- /* Tooltip animation */
263
- animation: graphql-tooltip-fade-in 0.2s ease-out;
264
- }
265
-
266
- @keyframes graphql-tooltip-fade-in {
267
- from {
268
- opacity: 0;
269
- transform: translateY(4px);
270
- }
271
- to {
272
- opacity: 1;
273
- transform: translateY(0);
274
- }
275
- }
276
-
277
- /* Ensure tooltips appear above other content */
278
- .graphql-hover-tooltip .rt-Card {
279
- box-shadow: 0 10px 38px -10px rgba(22, 23, 24, 0.35),
280
- 0 10px 20px -15px rgba(22, 23, 24, 0.2);
281
- }
282
- `