@antigenic-oss/paint 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 (158) hide show
  1. package/LICENSE +178 -0
  2. package/NOTICE +4 -0
  3. package/README.md +180 -0
  4. package/bin/paint.js +266 -0
  5. package/next-env.d.ts +6 -0
  6. package/next.config.ts +19 -0
  7. package/package.json +81 -0
  8. package/postcss.config.mjs +8 -0
  9. package/public/dev-editor-inspector.js +1872 -0
  10. package/src/app/api/claude/analyze/route.ts +319 -0
  11. package/src/app/api/claude/apply/route.ts +185 -0
  12. package/src/app/api/claude/pick-folder/route.ts +64 -0
  13. package/src/app/api/claude/scan/route.ts +221 -0
  14. package/src/app/api/claude/status/route.ts +55 -0
  15. package/src/app/api/project/scan/route.ts +634 -0
  16. package/src/app/api/project-scan/css-variables/route.ts +238 -0
  17. package/src/app/api/project-scan/route.ts +40 -0
  18. package/src/app/api/project-scan/tailwind-config/route.ts +172 -0
  19. package/src/app/api/proxy/[[...path]]/route.ts +2400 -0
  20. package/src/app/docs/DocsClient.tsx +322 -0
  21. package/src/app/docs/layout.tsx +7 -0
  22. package/src/app/docs/page.tsx +855 -0
  23. package/src/app/globals.css +176 -0
  24. package/src/app/layout.tsx +19 -0
  25. package/src/app/page.tsx +46 -0
  26. package/src/bridge/api-handlers.ts +885 -0
  27. package/src/bridge/proxy-handler.ts +329 -0
  28. package/src/bridge/server.ts +113 -0
  29. package/src/components/BreakpointTabs.tsx +72 -0
  30. package/src/components/ChangeSummaryModal.tsx +267 -0
  31. package/src/components/ConnectModal.tsx +994 -0
  32. package/src/components/Editor.tsx +90 -0
  33. package/src/components/PageSelector.tsx +208 -0
  34. package/src/components/PreviewFrame.tsx +299 -0
  35. package/src/components/ProjectFolderBanner.tsx +91 -0
  36. package/src/components/ResponsiveToolbar.tsx +222 -0
  37. package/src/components/TargetSelector.tsx +243 -0
  38. package/src/components/TopBar.tsx +315 -0
  39. package/src/components/common/CollapsibleSection.tsx +36 -0
  40. package/src/components/common/ColorPicker.tsx +920 -0
  41. package/src/components/common/EditablePre.tsx +136 -0
  42. package/src/components/common/ErrorBoundary.tsx +65 -0
  43. package/src/components/common/ResizablePanel.tsx +83 -0
  44. package/src/components/common/ScanAnimation.tsx +76 -0
  45. package/src/components/common/ToastContainer.tsx +97 -0
  46. package/src/components/common/UnitInput.tsx +77 -0
  47. package/src/components/common/VariableColorPicker.tsx +622 -0
  48. package/src/components/left-panel/AddElementPanel.tsx +237 -0
  49. package/src/components/left-panel/ComponentsPanel.tsx +609 -0
  50. package/src/components/left-panel/IconSidebar.tsx +99 -0
  51. package/src/components/left-panel/LayerNode.tsx +874 -0
  52. package/src/components/left-panel/LayerSearch.tsx +23 -0
  53. package/src/components/left-panel/LayersPanel.tsx +52 -0
  54. package/src/components/left-panel/LeftPanel.tsx +122 -0
  55. package/src/components/left-panel/PagesPanel.tsx +114 -0
  56. package/src/components/left-panel/icons.tsx +162 -0
  57. package/src/components/left-panel/terminal/ScanOverlay.tsx +66 -0
  58. package/src/components/left-panel/terminal/TerminalPanel.tsx +217 -0
  59. package/src/components/right-panel/ElementLogBox.tsx +248 -0
  60. package/src/components/right-panel/PanelTabs.tsx +83 -0
  61. package/src/components/right-panel/RightPanel.tsx +41 -0
  62. package/src/components/right-panel/changes/AiScanResultPanel.tsx +285 -0
  63. package/src/components/right-panel/changes/ChangeEntry.tsx +59 -0
  64. package/src/components/right-panel/changes/ChangelogActions.tsx +105 -0
  65. package/src/components/right-panel/changes/ChangesPanel.tsx +1474 -0
  66. package/src/components/right-panel/claude/ApplyConfirmModal.tsx +376 -0
  67. package/src/components/right-panel/claude/ClaudeErrorState.tsx +125 -0
  68. package/src/components/right-panel/claude/ClaudeIntegrationPanel.tsx +482 -0
  69. package/src/components/right-panel/claude/ClaudeProgressIndicator.tsx +76 -0
  70. package/src/components/right-panel/claude/DiffCard.tsx +130 -0
  71. package/src/components/right-panel/claude/DiffViewer.tsx +54 -0
  72. package/src/components/right-panel/claude/ProjectRootSelector.tsx +275 -0
  73. package/src/components/right-panel/claude/ResultsSummary.tsx +119 -0
  74. package/src/components/right-panel/claude/SetupFlow.tsx +315 -0
  75. package/src/components/right-panel/console/ConsolePanel.tsx +209 -0
  76. package/src/components/right-panel/design/AppearanceSection.tsx +703 -0
  77. package/src/components/right-panel/design/BackgroundSection.tsx +516 -0
  78. package/src/components/right-panel/design/BorderSection.tsx +161 -0
  79. package/src/components/right-panel/design/CSSRawView.tsx +412 -0
  80. package/src/components/right-panel/design/DesignCSSTabToggle.tsx +51 -0
  81. package/src/components/right-panel/design/DesignPanel.tsx +275 -0
  82. package/src/components/right-panel/design/ElementBreadcrumb.tsx +51 -0
  83. package/src/components/right-panel/design/GradientEditor.tsx +726 -0
  84. package/src/components/right-panel/design/LayoutSection.tsx +1948 -0
  85. package/src/components/right-panel/design/PositionSection.tsx +865 -0
  86. package/src/components/right-panel/design/PropertiesSection.tsx +86 -0
  87. package/src/components/right-panel/design/SVGSection.tsx +361 -0
  88. package/src/components/right-panel/design/ShadowBlurSection.tsx +227 -0
  89. package/src/components/right-panel/design/SizeSection.tsx +183 -0
  90. package/src/components/right-panel/design/TextSection.tsx +719 -0
  91. package/src/components/right-panel/design/icons.tsx +948 -0
  92. package/src/components/right-panel/design/inputs/BoxModelPreview.tsx +467 -0
  93. package/src/components/right-panel/design/inputs/ColorInput.tsx +43 -0
  94. package/src/components/right-panel/design/inputs/CompactInput.tsx +333 -0
  95. package/src/components/right-panel/design/inputs/DraggableLabel.tsx +118 -0
  96. package/src/components/right-panel/design/inputs/IconToggleGroup.tsx +54 -0
  97. package/src/components/right-panel/design/inputs/LinkedInputPair.tsx +174 -0
  98. package/src/components/right-panel/design/inputs/SectionHeader.tsx +79 -0
  99. package/src/components/right-panel/variables/VariablesPanel.tsx +388 -0
  100. package/src/hooks/useBridge.ts +95 -0
  101. package/src/hooks/useChangeTracker.ts +563 -0
  102. package/src/hooks/useClaudeAPI.ts +118 -0
  103. package/src/hooks/useDOMTree.ts +25 -0
  104. package/src/hooks/useKeyboardShortcuts.ts +76 -0
  105. package/src/hooks/usePostMessage.ts +589 -0
  106. package/src/hooks/useProjectScan.ts +204 -0
  107. package/src/hooks/useResizable.ts +20 -0
  108. package/src/hooks/useSelectedElement.ts +51 -0
  109. package/src/hooks/useTargetUrl.ts +81 -0
  110. package/src/inspector/DOMTraverser.ts +71 -0
  111. package/src/inspector/ElementSelector.ts +23 -0
  112. package/src/inspector/HoverHighlighter.ts +54 -0
  113. package/src/inspector/SelectionHighlighter.ts +27 -0
  114. package/src/inspector/StyleExtractor.ts +19 -0
  115. package/src/inspector/inspector.ts +17 -0
  116. package/src/inspector/messaging.ts +30 -0
  117. package/src/lib/apiBase.ts +15 -0
  118. package/src/lib/classifyElement.ts +430 -0
  119. package/src/lib/claude-bin.ts +197 -0
  120. package/src/lib/claude-stream.ts +158 -0
  121. package/src/lib/clientProjectScanner.ts +344 -0
  122. package/src/lib/componentMatcher.ts +156 -0
  123. package/src/lib/constants.ts +573 -0
  124. package/src/lib/cssVariableUtils.ts +409 -0
  125. package/src/lib/diffParser.ts +206 -0
  126. package/src/lib/folderPicker.ts +84 -0
  127. package/src/lib/gradientParser.ts +160 -0
  128. package/src/lib/projectScanner.ts +355 -0
  129. package/src/lib/promptBuilder.ts +402 -0
  130. package/src/lib/shadowParser.ts +124 -0
  131. package/src/lib/tailwindClassParser.ts +248 -0
  132. package/src/lib/textShadowUtils.ts +106 -0
  133. package/src/lib/utils.ts +299 -0
  134. package/src/lib/validatePath.ts +40 -0
  135. package/src/proxy.ts +92 -0
  136. package/src/server/terminal-server.ts +104 -0
  137. package/src/store/changeSlice.ts +288 -0
  138. package/src/store/claudeSlice.ts +222 -0
  139. package/src/store/componentSlice.ts +90 -0
  140. package/src/store/consoleSlice.ts +51 -0
  141. package/src/store/cssVariableSlice.ts +94 -0
  142. package/src/store/elementSlice.ts +78 -0
  143. package/src/store/index.ts +35 -0
  144. package/src/store/terminalSlice.ts +30 -0
  145. package/src/store/treeSlice.ts +69 -0
  146. package/src/store/uiSlice.ts +327 -0
  147. package/src/types/changelog.ts +49 -0
  148. package/src/types/claude.ts +131 -0
  149. package/src/types/component.ts +49 -0
  150. package/src/types/cssVariables.ts +18 -0
  151. package/src/types/element.ts +21 -0
  152. package/src/types/file-system-access.d.ts +27 -0
  153. package/src/types/gradient.ts +12 -0
  154. package/src/types/messages.ts +392 -0
  155. package/src/types/shadow.ts +8 -0
  156. package/src/types/tree.ts +9 -0
  157. package/tsconfig.json +42 -0
  158. package/tsconfig.server.json +12 -0
@@ -0,0 +1,237 @@
1
+ 'use client'
2
+
3
+ import { useCallback } from 'react'
4
+ import { useEditorStore } from '@/store'
5
+ import { sendViaIframe } from '@/hooks/usePostMessage'
6
+
7
+ interface ElementType {
8
+ tag: string
9
+ label: string
10
+ description: string
11
+ placeholderText: string
12
+ defaultStyles?: Record<string, string>
13
+ }
14
+
15
+ interface ElementCategory {
16
+ name: string
17
+ elements: ElementType[]
18
+ }
19
+
20
+ const ELEMENT_CATEGORIES: ElementCategory[] = [
21
+ {
22
+ name: 'Structure',
23
+ elements: [
24
+ {
25
+ tag: 'div',
26
+ label: 'Div',
27
+ description: 'Generic container',
28
+ placeholderText: 'Div',
29
+ defaultStyles: {
30
+ width: '100%',
31
+ height: '100px',
32
+ 'background-color': 'green',
33
+ display: 'flex',
34
+ 'justify-content': 'center',
35
+ 'align-items': 'center',
36
+ },
37
+ },
38
+ {
39
+ tag: 'section',
40
+ label: 'Section',
41
+ description: 'Semantic section',
42
+ placeholderText: 'Section',
43
+ defaultStyles: {
44
+ width: '100%',
45
+ height: '100px',
46
+ 'background-color': 'green',
47
+ display: 'flex',
48
+ 'justify-content': 'center',
49
+ 'align-items': 'center',
50
+ },
51
+ },
52
+ ],
53
+ },
54
+ {
55
+ name: 'Text',
56
+ elements: [
57
+ {
58
+ tag: 'h1',
59
+ label: 'H1',
60
+ description: 'Main heading',
61
+ placeholderText: 'Heading 1',
62
+ },
63
+ {
64
+ tag: 'h2',
65
+ label: 'H2',
66
+ description: 'Sub heading',
67
+ placeholderText: 'Heading 2',
68
+ },
69
+ {
70
+ tag: 'h3',
71
+ label: 'H3',
72
+ description: 'Section heading',
73
+ placeholderText: 'Heading 3',
74
+ },
75
+ {
76
+ tag: 'h4',
77
+ label: 'H4',
78
+ description: 'Sub-section heading',
79
+ placeholderText: 'Heading 4',
80
+ },
81
+ {
82
+ tag: 'h5',
83
+ label: 'H5',
84
+ description: 'Minor heading',
85
+ placeholderText: 'Heading 5',
86
+ },
87
+ {
88
+ tag: 'h6',
89
+ label: 'H6',
90
+ description: 'Smallest heading',
91
+ placeholderText: 'Heading 6',
92
+ },
93
+ {
94
+ tag: 'p',
95
+ label: 'Paragraph',
96
+ description: 'Text paragraph',
97
+ placeholderText: 'Paragraph text',
98
+ },
99
+ ],
100
+ },
101
+ ]
102
+
103
+ function ElementItem({
104
+ element,
105
+ onInsert,
106
+ }: {
107
+ element: ElementType
108
+ onInsert: (el: ElementType) => void
109
+ }) {
110
+ const handleDragStart = useCallback(
111
+ (e: React.DragEvent) => {
112
+ e.dataTransfer.setData(
113
+ 'application/x-dev-editor-element',
114
+ JSON.stringify({
115
+ tag: element.tag,
116
+ placeholderText: element.placeholderText,
117
+ defaultStyles: element.defaultStyles,
118
+ }),
119
+ )
120
+ e.dataTransfer.effectAllowed = 'copy'
121
+ },
122
+ [element],
123
+ )
124
+
125
+ return (
126
+ <button
127
+ draggable
128
+ onDragStart={handleDragStart}
129
+ onClick={() => onInsert(element)}
130
+ className="flex items-center gap-2 w-full text-left"
131
+ style={{
132
+ padding: '6px 8px',
133
+ borderRadius: 4,
134
+ border: 'none',
135
+ background: 'transparent',
136
+ color: 'var(--text-primary)',
137
+ cursor: 'grab',
138
+ fontSize: 11,
139
+ transition: 'background-color 0.1s',
140
+ }}
141
+ onMouseEnter={(e) => {
142
+ e.currentTarget.style.background = 'var(--bg-hover)'
143
+ }}
144
+ onMouseLeave={(e) => {
145
+ e.currentTarget.style.background = 'transparent'
146
+ }}
147
+ title={`Drag to add or click to insert <${element.tag}>`}
148
+ >
149
+ <span
150
+ className="flex-shrink-0 flex items-center justify-center"
151
+ style={{
152
+ width: 28,
153
+ height: 22,
154
+ borderRadius: 3,
155
+ background: 'var(--bg-tertiary)',
156
+ color: 'var(--accent)',
157
+ fontSize: 10,
158
+ fontWeight: 600,
159
+ fontFamily: 'monospace',
160
+ }}
161
+ >
162
+ {element.tag}
163
+ </span>
164
+ <span style={{ color: 'var(--text-secondary)', fontSize: 11 }}>
165
+ {element.description}
166
+ </span>
167
+ </button>
168
+ )
169
+ }
170
+
171
+ export function AddElementPanel() {
172
+ const selectorPath = useEditorStore((s) => s.selectorPath)
173
+
174
+ const handleInsert = useCallback(
175
+ (element: ElementType) => {
176
+ if (!selectorPath) return
177
+ sendViaIframe({
178
+ type: 'INSERT_ELEMENT',
179
+ payload: {
180
+ tagName: element.tag,
181
+ parentSelectorPath: selectorPath,
182
+ placeholderText: element.placeholderText,
183
+ defaultStyles: element.defaultStyles,
184
+ },
185
+ })
186
+ },
187
+ [selectorPath],
188
+ )
189
+
190
+ return (
191
+ <div
192
+ className="flex flex-col flex-1 overflow-y-auto"
193
+ style={{ padding: '8px' }}
194
+ >
195
+ {!selectorPath && (
196
+ <div
197
+ className="text-xs"
198
+ style={{
199
+ color: 'var(--text-muted)',
200
+ padding: '8px',
201
+ marginBottom: 8,
202
+ borderRadius: 4,
203
+ background: 'var(--bg-tertiary)',
204
+ }}
205
+ >
206
+ Select a parent element first, then click an element to insert it. Or
207
+ drag an element onto the preview.
208
+ </div>
209
+ )}
210
+ {ELEMENT_CATEGORIES.map((category) => (
211
+ <div key={category.name} style={{ marginBottom: 12 }}>
212
+ <div
213
+ className="text-xs font-medium"
214
+ style={{
215
+ color: 'var(--text-muted)',
216
+ padding: '4px 8px',
217
+ textTransform: 'uppercase',
218
+ letterSpacing: '0.05em',
219
+ fontSize: 10,
220
+ }}
221
+ >
222
+ {category.name}
223
+ </div>
224
+ <div className="flex flex-col">
225
+ {category.elements.map((element) => (
226
+ <ElementItem
227
+ key={element.tag}
228
+ element={element}
229
+ onInsert={handleInsert}
230
+ />
231
+ ))}
232
+ </div>
233
+ </div>
234
+ ))}
235
+ </div>
236
+ )
237
+ }