@oferitz/graphiq 0.1.0

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 (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +210 -0
  3. package/dist/components/GraphiQ.d.ts +3 -0
  4. package/dist/components/GraphiQ.d.ts.map +1 -0
  5. package/dist/components/GraphiQProvider.d.ts +3 -0
  6. package/dist/components/GraphiQProvider.d.ts.map +1 -0
  7. package/dist/components/editor/HeadersEditor.d.ts +6 -0
  8. package/dist/components/editor/HeadersEditor.d.ts.map +1 -0
  9. package/dist/components/editor/QueryEditor.d.ts +6 -0
  10. package/dist/components/editor/QueryEditor.d.ts.map +1 -0
  11. package/dist/components/editor/ResponseViewer.d.ts +6 -0
  12. package/dist/components/editor/ResponseViewer.d.ts.map +1 -0
  13. package/dist/components/editor/VariablesEditor.d.ts +6 -0
  14. package/dist/components/editor/VariablesEditor.d.ts.map +1 -0
  15. package/dist/components/editor/use-codemirror.d.ts +15 -0
  16. package/dist/components/editor/use-codemirror.d.ts.map +1 -0
  17. package/dist/components/explorer/QueryExplorer.d.ts +6 -0
  18. package/dist/components/explorer/QueryExplorer.d.ts.map +1 -0
  19. package/dist/components/history/QueryHistory.d.ts +6 -0
  20. package/dist/components/history/QueryHistory.d.ts.map +1 -0
  21. package/dist/components/schema/SchemaExplorer.d.ts +6 -0
  22. package/dist/components/schema/SchemaExplorer.d.ts.map +1 -0
  23. package/dist/components/sidebar/Sidebar.d.ts +10 -0
  24. package/dist/components/sidebar/Sidebar.d.ts.map +1 -0
  25. package/dist/components/tabs/Tab.d.ts +10 -0
  26. package/dist/components/tabs/Tab.d.ts.map +1 -0
  27. package/dist/components/tabs/TabBar.d.ts +6 -0
  28. package/dist/components/tabs/TabBar.d.ts.map +1 -0
  29. package/dist/components/toolbar/ExecuteButton.d.ts +9 -0
  30. package/dist/components/toolbar/ExecuteButton.d.ts.map +1 -0
  31. package/dist/components/toolbar/PrettifyButton.d.ts +7 -0
  32. package/dist/components/toolbar/PrettifyButton.d.ts.map +1 -0
  33. package/dist/components/toolbar/Toolbar.d.ts +7 -0
  34. package/dist/components/toolbar/Toolbar.d.ts.map +1 -0
  35. package/dist/components/ui/Resizable.d.ts +13 -0
  36. package/dist/components/ui/Resizable.d.ts.map +1 -0
  37. package/dist/graphiq.cjs +28 -0
  38. package/dist/graphiq.cjs.map +1 -0
  39. package/dist/graphiq.js +20903 -0
  40. package/dist/graphiq.js.map +1 -0
  41. package/dist/hooks/use-graphiq.d.ts +18 -0
  42. package/dist/hooks/use-graphiq.d.ts.map +1 -0
  43. package/dist/hooks/use-query.d.ts +8 -0
  44. package/dist/hooks/use-query.d.ts.map +1 -0
  45. package/dist/hooks/use-schema.d.ts +6 -0
  46. package/dist/hooks/use-schema.d.ts.map +1 -0
  47. package/dist/index.d.ts +25 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/lib/cn.d.ts +3 -0
  50. package/dist/lib/cn.d.ts.map +1 -0
  51. package/dist/lib/fetcher.d.ts +3 -0
  52. package/dist/lib/fetcher.d.ts.map +1 -0
  53. package/dist/lib/formatter.d.ts +2 -0
  54. package/dist/lib/formatter.d.ts.map +1 -0
  55. package/dist/lib/introspection.d.ts +4 -0
  56. package/dist/lib/introspection.d.ts.map +1 -0
  57. package/dist/lib/storage.d.ts +3 -0
  58. package/dist/lib/storage.d.ts.map +1 -0
  59. package/dist/stores/create-store.d.ts +19 -0
  60. package/dist/stores/create-store.d.ts.map +1 -0
  61. package/dist/stores/editor-store.d.ts +11 -0
  62. package/dist/stores/editor-store.d.ts.map +1 -0
  63. package/dist/stores/execution-store.d.ts +12 -0
  64. package/dist/stores/execution-store.d.ts.map +1 -0
  65. package/dist/stores/history-store.d.ts +10 -0
  66. package/dist/stores/history-store.d.ts.map +1 -0
  67. package/dist/stores/schema-store.d.ts +11 -0
  68. package/dist/stores/schema-store.d.ts.map +1 -0
  69. package/dist/stores/tabs-store.d.ts +11 -0
  70. package/dist/stores/tabs-store.d.ts.map +1 -0
  71. package/dist/stores/ui-store.d.ts +8 -0
  72. package/dist/stores/ui-store.d.ts.map +1 -0
  73. package/dist/style.css +3 -0
  74. package/dist/styles/codemirror-theme.d.ts +8 -0
  75. package/dist/styles/codemirror-theme.d.ts.map +1 -0
  76. package/dist/styles/variants.d.ts +81 -0
  77. package/dist/styles/variants.d.ts.map +1 -0
  78. package/dist/types/fetcher.d.ts +22 -0
  79. package/dist/types/fetcher.d.ts.map +1 -0
  80. package/dist/types/index.d.ts +5 -0
  81. package/dist/types/index.d.ts.map +1 -0
  82. package/dist/types/plugin.d.ts +15 -0
  83. package/dist/types/plugin.d.ts.map +1 -0
  84. package/dist/types/props.d.ts +50 -0
  85. package/dist/types/props.d.ts.map +1 -0
  86. package/dist/types/store.d.ts +23 -0
  87. package/dist/types/store.d.ts.map +1 -0
  88. package/package.json +100 -0
  89. package/src/styles/animations.css +35 -0
  90. package/src/styles/base.css +193 -0
  91. package/src/styles/codemirror-theme.ts +46 -0
  92. package/src/styles/variants.ts +25 -0
package/package.json ADDED
@@ -0,0 +1,100 @@
1
+
2
+ {
3
+ "name": "@oferitz/graphiq",
4
+ "version": "0.1.0",
5
+ "description": "A modern, lightweight GraphQL IDE component for React",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "sideEffects": ["*.css"],
9
+ "main": "./dist/graphiq.cjs",
10
+ "module": "./dist/graphiq.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "import": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/graphiq.js"
17
+ },
18
+ "require": {
19
+ "types": "./dist/index.d.cts",
20
+ "default": "./dist/graphiq.cjs"
21
+ }
22
+ },
23
+ "./style.css": "./dist/style.css",
24
+ "./styles": "./src/styles/base.css"
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "src/styles",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "scripts": {
33
+ "dev": "vite --config vite.playground.config.ts",
34
+ "build": "vite build && tsc --project tsconfig.build.json --emitDeclarationOnly --outDir dist",
35
+ "preview": "vite preview --config vite.playground.config.ts",
36
+ "lint": "oxlint src/",
37
+ "format": "oxlint --fix src/",
38
+ "typecheck": "tsc --noEmit",
39
+ "test": "vitest run",
40
+ "test:watch": "vitest",
41
+ "test:coverage": "vitest run --coverage",
42
+ "e2e": "playwright test",
43
+ "prepublishOnly": "bun run build",
44
+ "changeset": "changeset",
45
+ "release": "changeset publish"
46
+ },
47
+ "peerDependencies": {
48
+ "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0",
49
+ "react": "^18.0.0 || ^19.0.0",
50
+ "react-dom": "^18.0.0 || ^19.0.0"
51
+ },
52
+ "dependencies": {
53
+ "@codemirror/lang-json": "^6.0.2",
54
+ "@codemirror/state": "^6.6.0",
55
+ "@codemirror/view": "^6.40.0",
56
+ "@phosphor-icons/react": "^2.1.10",
57
+ "clsx": "^2.1.1",
58
+ "cm6-graphql": "^0.2.1",
59
+ "codemirror": "^6.0.2",
60
+ "tailwind-merge": "^3.5.0",
61
+ "tailwind-variants": "^3.2.2",
62
+ "zustand": "^5.0.12"
63
+ },
64
+ "devDependencies": {
65
+ "@changesets/cli": "^2.30.0",
66
+ "@playwright/test": "^1.58.2",
67
+ "@tailwindcss/vite": "^4.2.2",
68
+ "@testing-library/jest-dom": "^6.9.1",
69
+ "@testing-library/react": "^16.3.2",
70
+ "@types/react": "^19.2.14",
71
+ "@types/react-dom": "^19.2.3",
72
+ "@vitejs/plugin-react": "^6.0.1",
73
+ "graphql": "^16.13.2",
74
+ "graphql-http": "^1.22.4",
75
+ "jsdom": "^29.0.1",
76
+ "oxlint": "^1.57.0",
77
+ "react": "^19.2.4",
78
+ "react-dom": "^19.2.4",
79
+ "tailwindcss": "^4.2.2",
80
+ "typescript": "^5.9.3",
81
+ "vite": "^8.0.3",
82
+ "vitest": "^4.1.2"
83
+ },
84
+ "keywords": [
85
+ "graphql",
86
+ "graphiql",
87
+ "ide",
88
+ "react",
89
+ "codemirror",
90
+ "developer-tools"
91
+ ],
92
+ "repository": {
93
+ "type": "git",
94
+ "url": "https://github.com/oferitz/graphiq.git"
95
+ },
96
+ "homepage": "https://github.com/oferitz/graphiq",
97
+ "bugs": {
98
+ "url": "https://github.com/oferitz/graphiq/issues"
99
+ }
100
+ }
@@ -0,0 +1,35 @@
1
+ @keyframes gq-pulse {
2
+ 0%,
3
+ 100% {
4
+ opacity: 1;
5
+ }
6
+ 50% {
7
+ opacity: 0.7;
8
+ }
9
+ }
10
+
11
+ @keyframes gq-shimmer {
12
+ 0% {
13
+ transform: translateX(-100%);
14
+ }
15
+ 100% {
16
+ transform: translateX(100%);
17
+ }
18
+ }
19
+
20
+ @keyframes gq-fade-in {
21
+ from {
22
+ opacity: 0;
23
+ transform: translateY(4px);
24
+ }
25
+ to {
26
+ opacity: 1;
27
+ transform: translateY(0);
28
+ }
29
+ }
30
+
31
+ @keyframes gq-spin {
32
+ to {
33
+ transform: rotate(360deg);
34
+ }
35
+ }
@@ -0,0 +1,193 @@
1
+ @import "tailwindcss";
2
+
3
+ /* Ensure Tailwind scans all component files for classes */
4
+ @source "../";
5
+
6
+ /*
7
+ * GraphiQ Design Tokens — "Surgical Precision"
8
+ * Ultra-compact, near-monochrome, one teal accent.
9
+ * Every pixel earns its place.
10
+ */
11
+
12
+ :root {
13
+ /* === Background Layers (zinc-black scale) === */
14
+ --gq-bg: #09090b;
15
+ --gq-bg-secondary: #0f0f12;
16
+ --gq-bg-tertiary: #18181b;
17
+ --gq-bg-elevated: #1e1e23;
18
+
19
+ /* === Text Hierarchy === */
20
+ --gq-text: #fafafa;
21
+ --gq-text-secondary: #a1a1aa;
22
+ --gq-text-tertiary: #52525b;
23
+
24
+ /* === Accent — muted teal, not neon === */
25
+ --gq-accent: #2dd4bf;
26
+ --gq-accent-hover: #5eead4;
27
+ --gq-accent-muted: #134e4a;
28
+ --gq-accent-subtle: #0d3330;
29
+
30
+ /* === Semantic States === */
31
+ --gq-success: #34d399;
32
+ --gq-error: #f87171;
33
+ --gq-warning: #fbbf24;
34
+ --gq-info: #60a5fa;
35
+
36
+ /* === Borders (barely visible) === */
37
+ --gq-border: #1e1e23;
38
+ --gq-border-active: #3f3f46;
39
+ --gq-separator: #18181b;
40
+
41
+ /* === Typography === */
42
+ --gq-font-display: "DM Sans", system-ui, sans-serif;
43
+ --gq-font-sans: "DM Sans", system-ui, sans-serif;
44
+ --gq-font-mono: "Geist Mono", "JetBrains Mono", ui-monospace, monospace;
45
+
46
+ /* === Spacing & Sizing (compact) === */
47
+ --gq-panel-gap: 1px;
48
+ --gq-radius: 4px;
49
+ --gq-toolbar-height: 36px;
50
+ --gq-sidebar-width: 40px;
51
+ --gq-editor-font-size: 13px;
52
+ --gq-editor-line-height: 1.6;
53
+
54
+ /* === Syntax Highlighting (muted, cohesive) === */
55
+ --gq-syn-keyword: #2dd4bf;
56
+ --gq-syn-type: #60a5fa;
57
+ --gq-syn-field: #d4d4d8;
58
+ --gq-syn-string: #a3e635;
59
+ --gq-syn-number: #fbbf24;
60
+ --gq-syn-comment: #3f3f46;
61
+ --gq-syn-directive: #f472b6;
62
+ --gq-syn-variable: #c084fc;
63
+ --gq-syn-punctuation: #52525b;
64
+
65
+ /* === Animation === */
66
+ --gq-ease: cubic-bezier(0.16, 1, 0.3, 1);
67
+ --gq-duration-fast: 100ms;
68
+ --gq-duration-normal: 150ms;
69
+ --gq-duration-slow: 250ms;
70
+ }
71
+
72
+ /* Base reset for graphiq root */
73
+ .gq-root {
74
+ color-scheme: dark;
75
+ -webkit-font-smoothing: antialiased;
76
+ -moz-osx-font-smoothing: grayscale;
77
+ }
78
+
79
+ /* CodeMirror theme — surgical dark */
80
+ .gq-root .cm-editor {
81
+ height: 100%;
82
+ background: var(--gq-bg-secondary);
83
+ color: var(--gq-text);
84
+ font-size: var(--gq-editor-font-size);
85
+ }
86
+
87
+ .gq-root .cm-editor .cm-scroller {
88
+ font-family: var(--gq-font-mono);
89
+ line-height: var(--gq-editor-line-height);
90
+ }
91
+
92
+ .gq-root .cm-editor .cm-gutters {
93
+ background: var(--gq-bg-secondary);
94
+ border-right: 1px solid var(--gq-border);
95
+ color: var(--gq-text-tertiary);
96
+ font-size: 11px;
97
+ min-width: 36px;
98
+ }
99
+
100
+ .gq-root .cm-editor .cm-activeLineGutter {
101
+ background: transparent;
102
+ color: var(--gq-text-secondary);
103
+ }
104
+
105
+ .gq-root .cm-editor .cm-activeLine {
106
+ background: rgba(255, 255, 255, 0.02);
107
+ }
108
+
109
+ .gq-root .cm-editor .cm-cursor {
110
+ border-left: 1.5px solid var(--gq-accent);
111
+ }
112
+
113
+ .gq-root .cm-editor .cm-selectionBackground {
114
+ background: var(--gq-accent-subtle) !important;
115
+ }
116
+
117
+ .gq-root .cm-editor.cm-focused .cm-selectionBackground {
118
+ background: var(--gq-accent-muted) !important;
119
+ }
120
+
121
+ .gq-root .cm-editor .cm-tooltip {
122
+ background: var(--gq-bg-elevated);
123
+ border: 1px solid var(--gq-border-active);
124
+ border-radius: var(--gq-radius);
125
+ color: var(--gq-text);
126
+ font-size: 12px;
127
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
128
+ }
129
+
130
+ .gq-root .cm-editor .cm-tooltip-autocomplete ul li[aria-selected] {
131
+ background: var(--gq-accent-subtle);
132
+ color: var(--gq-accent);
133
+ }
134
+
135
+ .gq-root .cm-editor .cm-content {
136
+ caret-color: var(--gq-accent);
137
+ padding: 8px 0;
138
+ }
139
+
140
+ .gq-root .cm-editor .cm-line {
141
+ padding: 0 8px;
142
+ }
143
+
144
+ /* Scrollbar styling */
145
+ .gq-root ::-webkit-scrollbar {
146
+ width: 6px;
147
+ height: 6px;
148
+ }
149
+
150
+ .gq-root ::-webkit-scrollbar-track {
151
+ background: transparent;
152
+ }
153
+
154
+ .gq-root ::-webkit-scrollbar-thumb {
155
+ background: var(--gq-border-active);
156
+ border-radius: 3px;
157
+ }
158
+
159
+ .gq-root ::-webkit-scrollbar-thumb:hover {
160
+ background: var(--gq-text-tertiary);
161
+ }
162
+
163
+ /* Register tokens with Tailwind v4 */
164
+ @theme inline {
165
+ --color-gq-bg: var(--gq-bg);
166
+ --color-gq-bg-secondary: var(--gq-bg-secondary);
167
+ --color-gq-bg-tertiary: var(--gq-bg-tertiary);
168
+ --color-gq-bg-elevated: var(--gq-bg-elevated);
169
+
170
+ --color-gq-text: var(--gq-text);
171
+ --color-gq-text-secondary: var(--gq-text-secondary);
172
+ --color-gq-text-tertiary: var(--gq-text-tertiary);
173
+
174
+ --color-gq-accent: var(--gq-accent);
175
+ --color-gq-accent-hover: var(--gq-accent-hover);
176
+ --color-gq-accent-muted: var(--gq-accent-muted);
177
+ --color-gq-accent-subtle: var(--gq-accent-subtle);
178
+
179
+ --color-gq-success: var(--gq-success);
180
+ --color-gq-error: var(--gq-error);
181
+ --color-gq-warning: var(--gq-warning);
182
+ --color-gq-info: var(--gq-info);
183
+
184
+ --color-gq-border: var(--gq-border);
185
+ --color-gq-border-active: var(--gq-border-active);
186
+ --color-gq-separator: var(--gq-separator);
187
+
188
+ --font-gq-display: var(--gq-font-display);
189
+ --font-gq-sans: var(--gq-font-sans);
190
+ --font-gq-mono: var(--gq-font-mono);
191
+
192
+ --radius-gq: var(--gq-radius);
193
+ }
@@ -0,0 +1,46 @@
1
+ import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
2
+ import { tags } from "@lezer/highlight";
3
+
4
+ /**
5
+ * GraphiQ syntax highlighting theme for CodeMirror 6.
6
+ * Uses CSS variables so consumers can customize colors.
7
+ */
8
+ export const graphiqHighlightStyle = HighlightStyle.define([
9
+ // Keywords: query, mutation, subscription, fragment, on
10
+ { tag: tags.keyword, color: "var(--gq-syn-keyword)" },
11
+ { tag: tags.definitionKeyword, color: "var(--gq-syn-keyword)", fontWeight: "500" },
12
+
13
+ // Field names
14
+ { tag: tags.propertyName, color: "var(--gq-syn-field)" },
15
+
16
+ // Types / atoms
17
+ { tag: tags.atom, color: "var(--gq-syn-type)" },
18
+ { tag: [tags.special(tags.name)], color: "var(--gq-syn-type)" },
19
+
20
+ // Strings
21
+ { tag: tags.string, color: "var(--gq-syn-string)" },
22
+
23
+ // Numbers
24
+ { tag: [tags.integer, tags.float], color: "var(--gq-syn-number)" },
25
+
26
+ // Booleans / null
27
+ { tag: tags.bool, color: "var(--gq-syn-number)" },
28
+ { tag: tags.null, color: "var(--gq-text-tertiary)" },
29
+
30
+ // Comments
31
+ { tag: tags.lineComment, color: "var(--gq-syn-comment)", fontStyle: "italic" },
32
+
33
+ // Variables ($name)
34
+ { tag: tags.variableName, color: "var(--gq-syn-variable)" },
35
+
36
+ // Directives (@skip, @include)
37
+ { tag: tags.modifier, color: "var(--gq-syn-directive)" },
38
+
39
+ // Arguments
40
+ { tag: tags.attributeName, color: "var(--gq-syn-variable)" },
41
+
42
+ // Punctuation
43
+ { tag: [tags.paren, tags.brace, tags.separator, tags.punctuation], color: "var(--gq-syn-punctuation)" },
44
+ ]);
45
+
46
+ export const graphiqSyntaxHighlighting = syntaxHighlighting(graphiqHighlightStyle);
@@ -0,0 +1,25 @@
1
+ import { tv } from "tailwind-variants";
2
+
3
+ export const graphiqVariants = tv({
4
+ slots: {
5
+ root: "gq-root flex h-full w-full bg-gq-bg text-gq-text font-gq-sans text-[13px] overflow-hidden",
6
+ sidebar:
7
+ "gq-sidebar flex flex-col items-center gap-0.5 py-1.5 bg-gq-bg border-r border-gq-border",
8
+ sidebarPanel:
9
+ "gq-sidebar-panel bg-gq-bg border-r border-gq-border overflow-y-auto",
10
+ editor: "gq-editor flex flex-col flex-1 min-w-0 bg-gq-bg-secondary",
11
+ toolbar:
12
+ "gq-toolbar flex items-center gap-1.5 px-2 bg-gq-bg border-b border-gq-border",
13
+ response:
14
+ "gq-response flex flex-col flex-1 min-w-0 bg-gq-bg-secondary",
15
+ executeButton:
16
+ "gq-execute inline-flex items-center justify-center gap-1 px-2.5 py-1 rounded-gq bg-gq-accent text-gq-bg font-gq-sans text-xs font-medium transition-all hover:bg-gq-accent-hover active:scale-[0.97]",
17
+ tabs: "gq-tabs flex items-center gap-0 border-b border-gq-border bg-gq-bg",
18
+ variablesEditor:
19
+ "gq-variables flex flex-col bg-gq-bg-secondary",
20
+ headersEditor:
21
+ "gq-headers flex flex-col bg-gq-bg-secondary",
22
+ },
23
+ });
24
+
25
+ export type GraphiQVariantSlots = keyof ReturnType<typeof graphiqVariants>;