@promakeai/inspector 0.2.1 → 1.0.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 (170) hide show
  1. package/dist/inspector.css +1 -0
  2. package/dist/inspector.js +8740 -0
  3. package/dist/packages/inspector/src/App.d.ts +5 -0
  4. package/dist/packages/inspector/src/App.d.ts.map +1 -0
  5. package/dist/packages/inspector/src/__tests__/App.test.d.ts +5 -0
  6. package/dist/packages/inspector/src/__tests__/App.test.d.ts.map +1 -0
  7. package/dist/packages/inspector/src/components/Badge.d.ts +9 -0
  8. package/dist/packages/inspector/src/components/Badge.d.ts.map +1 -0
  9. package/dist/packages/inspector/src/components/ControlBox/ContentArea.d.ts +10 -0
  10. package/dist/packages/inspector/src/components/ControlBox/ContentArea.d.ts.map +1 -0
  11. package/dist/packages/inspector/src/components/ControlBox/PromptInput.d.ts +12 -0
  12. package/dist/packages/inspector/src/components/ControlBox/PromptInput.d.ts.map +1 -0
  13. package/dist/packages/inspector/src/components/ControlBox/index.d.ts +21 -0
  14. package/dist/packages/inspector/src/components/ControlBox/index.d.ts.map +1 -0
  15. package/dist/packages/inspector/src/components/ImageEditor/UploadBox.d.ts +10 -0
  16. package/dist/packages/inspector/src/components/ImageEditor/UploadBox.d.ts.map +1 -0
  17. package/dist/packages/inspector/src/components/ImageEditor/index.d.ts +11 -0
  18. package/dist/packages/inspector/src/components/ImageEditor/index.d.ts.map +1 -0
  19. package/dist/packages/inspector/src/components/Overlay.d.ts +11 -0
  20. package/dist/packages/inspector/src/components/Overlay.d.ts.map +1 -0
  21. package/dist/packages/inspector/src/components/StyleEditor/BorderSection.d.ts +13 -0
  22. package/dist/packages/inspector/src/components/StyleEditor/BorderSection.d.ts.map +1 -0
  23. package/dist/packages/inspector/src/components/StyleEditor/ColorPicker.d.ts +13 -0
  24. package/dist/packages/inspector/src/components/StyleEditor/ColorPicker.d.ts.map +1 -0
  25. package/dist/packages/inspector/src/components/StyleEditor/DisplaySection.d.ts +13 -0
  26. package/dist/packages/inspector/src/components/StyleEditor/DisplaySection.d.ts.map +1 -0
  27. package/dist/packages/inspector/src/components/StyleEditor/ImageSection.d.ts +13 -0
  28. package/dist/packages/inspector/src/components/StyleEditor/ImageSection.d.ts.map +1 -0
  29. package/dist/packages/inspector/src/components/StyleEditor/LayoutSection.d.ts +13 -0
  30. package/dist/packages/inspector/src/components/StyleEditor/LayoutSection.d.ts.map +1 -0
  31. package/dist/packages/inspector/src/components/StyleEditor/NumberInput.d.ts +17 -0
  32. package/dist/packages/inspector/src/components/StyleEditor/NumberInput.d.ts.map +1 -0
  33. package/dist/packages/inspector/src/components/StyleEditor/SliderInput.d.ts +16 -0
  34. package/dist/packages/inspector/src/components/StyleEditor/SliderInput.d.ts.map +1 -0
  35. package/dist/packages/inspector/src/components/StyleEditor/SpacingSection.d.ts +13 -0
  36. package/dist/packages/inspector/src/components/StyleEditor/SpacingSection.d.ts.map +1 -0
  37. package/dist/packages/inspector/src/components/StyleEditor/TextSection.d.ts +13 -0
  38. package/dist/packages/inspector/src/components/StyleEditor/TextSection.d.ts.map +1 -0
  39. package/dist/packages/inspector/src/components/StyleEditor/index.d.ts +12 -0
  40. package/dist/packages/inspector/src/components/StyleEditor/index.d.ts.map +1 -0
  41. package/dist/packages/inspector/src/components/TextEditor/index.d.ts +11 -0
  42. package/dist/packages/inspector/src/components/TextEditor/index.d.ts.map +1 -0
  43. package/dist/packages/inspector/src/components/ui/CustomCollapsible.d.ts +26 -0
  44. package/dist/packages/inspector/src/components/ui/CustomCollapsible.d.ts.map +1 -0
  45. package/dist/packages/inspector/src/components/ui/button.d.ts +9 -0
  46. package/dist/packages/inspector/src/components/ui/button.d.ts.map +1 -0
  47. package/dist/packages/inspector/src/components/ui/color-picker.d.ts +10 -0
  48. package/dist/packages/inspector/src/components/ui/color-picker.d.ts.map +1 -0
  49. package/dist/packages/inspector/src/components/ui/input.d.ts +6 -0
  50. package/dist/packages/inspector/src/components/ui/input.d.ts.map +1 -0
  51. package/dist/packages/inspector/src/components/ui/popover.d.ts +8 -0
  52. package/dist/packages/inspector/src/components/ui/popover.d.ts.map +1 -0
  53. package/dist/packages/inspector/src/components/ui/select.d.ts +16 -0
  54. package/dist/packages/inspector/src/components/ui/select.d.ts.map +1 -0
  55. package/dist/packages/inspector/src/components/ui/slider.d.ts +5 -0
  56. package/dist/packages/inspector/src/components/ui/slider.d.ts.map +1 -0
  57. package/dist/packages/inspector/src/components/ui/textarea.d.ts +4 -0
  58. package/dist/packages/inspector/src/components/ui/textarea.d.ts.map +1 -0
  59. package/dist/packages/inspector/src/components/ui/tooltip.d.ts +8 -0
  60. package/dist/packages/inspector/src/components/ui/tooltip.d.ts.map +1 -0
  61. package/dist/packages/inspector/src/core/highlighter.d.ts +40 -0
  62. package/dist/packages/inspector/src/core/highlighter.d.ts.map +1 -0
  63. package/dist/packages/inspector/src/hooks/useMessageBridge.d.ts +9 -0
  64. package/dist/packages/inspector/src/hooks/useMessageBridge.d.ts.map +1 -0
  65. package/dist/packages/inspector/src/hooks/useStylePreview.d.ts +11 -0
  66. package/dist/packages/inspector/src/hooks/useStylePreview.d.ts.map +1 -0
  67. package/dist/packages/inspector/src/index.d.ts +16 -0
  68. package/dist/packages/inspector/src/index.d.ts.map +1 -0
  69. package/dist/packages/inspector/src/lib/utils.d.ts +3 -0
  70. package/dist/packages/inspector/src/lib/utils.d.ts.map +1 -0
  71. package/dist/packages/inspector/src/plugin.d.ts +4 -0
  72. package/dist/packages/inspector/src/plugin.d.ts.map +1 -0
  73. package/dist/packages/inspector/src/store/useInspectorStore.d.ts +13 -0
  74. package/dist/packages/inspector/src/store/useInspectorStore.d.ts.map +1 -0
  75. package/dist/packages/inspector/src/styles.d.ts +5 -0
  76. package/dist/packages/inspector/src/styles.d.ts.map +1 -0
  77. package/dist/packages/inspector/src/utils/colorUtils.d.ts +49 -0
  78. package/dist/packages/inspector/src/utils/colorUtils.d.ts.map +1 -0
  79. package/dist/packages/inspector/src/utils/elementNames.d.ts +7 -0
  80. package/dist/packages/inspector/src/utils/elementNames.d.ts.map +1 -0
  81. package/dist/packages/inspector/src/utils/elementUtils.d.ts +28 -0
  82. package/dist/packages/inspector/src/utils/elementUtils.d.ts.map +1 -0
  83. package/dist/packages/inspector/src/utils/errorTracker.d.ts +48 -0
  84. package/dist/packages/inspector/src/utils/errorTracker.d.ts.map +1 -0
  85. package/dist/packages/inspector/src/utils/inputStyles.d.ts +23 -0
  86. package/dist/packages/inspector/src/utils/inputStyles.d.ts.map +1 -0
  87. package/dist/packages/inspector/src/utils/styleUtils.d.ts +27 -0
  88. package/dist/packages/inspector/src/utils/styleUtils.d.ts.map +1 -0
  89. package/dist/packages/inspector/src/utils/tailwindMapper.d.ts +9 -0
  90. package/dist/packages/inspector/src/utils/tailwindMapper.d.ts.map +1 -0
  91. package/dist/packages/inspector/src/utils/urlTracker.d.ts +27 -0
  92. package/dist/packages/inspector/src/utils/urlTracker.d.ts.map +1 -0
  93. package/dist/packages/inspector/tsconfig.tsbuildinfo +1 -0
  94. package/dist/plugin.js +10 -1813
  95. package/package.json +86 -76
  96. package/src/App.tsx +912 -0
  97. package/src/__tests__/App.test.tsx +373 -0
  98. package/src/assets/fonts/Satoshi-Variable.woff +0 -0
  99. package/src/assets/fonts/Satoshi-Variable.woff2 +0 -0
  100. package/src/components/Badge.tsx +118 -0
  101. package/src/components/ControlBox/ContentArea.tsx +13 -0
  102. package/src/components/ControlBox/PromptInput.module.css +66 -0
  103. package/src/components/ControlBox/PromptInput.tsx +104 -0
  104. package/src/components/ControlBox/index.module.css +81 -0
  105. package/src/components/ControlBox/index.tsx +409 -0
  106. package/src/components/ImageEditor/UploadBox.module.css +69 -0
  107. package/src/components/ImageEditor/UploadBox.tsx +113 -0
  108. package/src/components/ImageEditor/index.module.css +11 -0
  109. package/src/components/ImageEditor/index.tsx +84 -0
  110. package/src/components/Overlay.tsx +157 -0
  111. package/src/components/StyleEditor/BorderSection.tsx +147 -0
  112. package/src/components/StyleEditor/ColorPicker.tsx +182 -0
  113. package/src/components/StyleEditor/DisplaySection.tsx +349 -0
  114. package/src/components/StyleEditor/ImageSection.tsx +105 -0
  115. package/src/components/StyleEditor/LayoutSection.tsx +63 -0
  116. package/src/components/StyleEditor/NumberInput.tsx +138 -0
  117. package/src/components/StyleEditor/SliderInput.tsx +121 -0
  118. package/src/components/StyleEditor/SpacingSection.tsx +365 -0
  119. package/src/components/StyleEditor/TextSection.tsx +381 -0
  120. package/src/components/StyleEditor/index.module.css +133 -0
  121. package/src/components/StyleEditor/index.tsx +612 -0
  122. package/src/components/StyleEditor/shared.module.css +193 -0
  123. package/src/components/TextEditor/index.module.css +31 -0
  124. package/src/components/TextEditor/index.tsx +166 -0
  125. package/src/components/ui/CustomCollapsible.tsx +159 -0
  126. package/src/components/ui/button.module.css +141 -0
  127. package/src/components/ui/button.tsx +73 -0
  128. package/src/components/ui/color-picker.module.css +112 -0
  129. package/src/components/ui/color-picker.tsx +146 -0
  130. package/src/components/ui/input.module.css +49 -0
  131. package/src/components/ui/input.tsx +34 -0
  132. package/src/components/ui/popover.module.css +42 -0
  133. package/src/components/ui/popover.tsx +59 -0
  134. package/src/components/ui/select.module.css +160 -0
  135. package/src/components/ui/select.tsx +216 -0
  136. package/src/components/ui/slider.module.css +75 -0
  137. package/src/components/ui/slider.tsx +60 -0
  138. package/src/components/ui/textarea.module.css +30 -0
  139. package/src/components/ui/textarea.tsx +23 -0
  140. package/src/components/ui/tooltip.module.css +11 -0
  141. package/src/components/ui/tooltip.tsx +37 -0
  142. package/src/core/highlighter.ts +197 -0
  143. package/src/hooks/useMessageBridge.ts +49 -0
  144. package/src/hooks/useStylePreview.ts +332 -0
  145. package/src/index.ts +20 -0
  146. package/src/lib/utils.ts +5 -0
  147. package/src/plugin.ts +11 -0
  148. package/src/store/useInspectorStore.ts +235 -0
  149. package/src/styles/fonts.css +15 -0
  150. package/src/styles/global.css +138 -0
  151. package/src/styles/variables.css +151 -0
  152. package/src/styles.ts +5 -0
  153. package/src/utils/colorUtils.ts +133 -0
  154. package/src/utils/elementNames.ts +103 -0
  155. package/src/utils/elementUtils.ts +90 -0
  156. package/src/utils/errorTracker.ts +186 -0
  157. package/src/utils/inputStyles.ts +30 -0
  158. package/src/utils/styleUtils.ts +226 -0
  159. package/src/utils/tailwindMapper.ts +554 -0
  160. package/src/utils/urlTracker.ts +75 -0
  161. package/src/vite-env.d.ts +7 -0
  162. package/README.md +0 -866
  163. package/dist/hook.d.ts +0 -115
  164. package/dist/hook.d.ts.map +0 -1
  165. package/dist/hook.js +0 -288
  166. package/dist/plugin.d.ts +0 -44
  167. package/dist/plugin.d.ts.map +0 -1
  168. package/dist/types.d.ts +0 -139
  169. package/dist/types.d.ts.map +0 -1
  170. package/dist/types.js +0 -7
@@ -0,0 +1,138 @@
1
+ /* Inspector Canvas Global Styles */
2
+ @import "./fonts.css";
3
+ @import "./variables.css";
4
+
5
+ /* Base scope for inspector */
6
+ #inspector-canvas-root {
7
+ font-family: var(--font-family-sans);
8
+ font-size: 14px;
9
+ line-height: 1.5;
10
+ font-weight: 400;
11
+ letter-spacing: -0.01em;
12
+ -webkit-font-smoothing: antialiased;
13
+ -moz-osx-font-smoothing: grayscale;
14
+ text-rendering: optimizeLegibility;
15
+ position: fixed;
16
+ top: 0;
17
+ left: 0;
18
+ right: 0;
19
+ bottom: 0;
20
+ pointer-events: none;
21
+ z-index: var(--z-inspector-root);
22
+ }
23
+
24
+ /* Thin scrollbar for element tags */
25
+ .inspector-element-tags::-webkit-scrollbar {
26
+ height: 4px;
27
+ }
28
+
29
+ .inspector-element-tags::-webkit-scrollbar-track {
30
+ background: transparent;
31
+ }
32
+
33
+ .inspector-element-tags::-webkit-scrollbar-thumb {
34
+ background: rgba(0, 0, 0, 0.2);
35
+ border-radius: 2px;
36
+ }
37
+
38
+ .inspector-element-tags::-webkit-scrollbar-thumb:hover {
39
+ background: rgba(0, 0, 0, 0.3);
40
+ }
41
+
42
+ /* Firefox */
43
+ .inspector-element-tags {
44
+ scrollbar-width: thin;
45
+ scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
46
+ }
47
+
48
+ /* When inspector is active, block all interactions with page */
49
+ #inspector-canvas-root.inspector-active {
50
+ pointer-events: auto;
51
+ }
52
+
53
+ /* Backdrop when inspector is active */
54
+ .inspector-backdrop {
55
+ position: fixed;
56
+ top: 0;
57
+ left: 0;
58
+ right: 0;
59
+ bottom: 0;
60
+ background: rgba(0, 0, 0, 0.01);
61
+ z-index: var(--z-inspector-backdrop);
62
+ pointer-events: auto;
63
+ cursor: default;
64
+ user-select: none;
65
+ }
66
+
67
+ /* Label specific fixes */
68
+ #inspector-canvas-root label {
69
+ font-family: "Satoshi", var(--font-family-sans);
70
+ font-weight: 500;
71
+ letter-spacing: -0.01em;
72
+ }
73
+
74
+ /* Overlay styles */
75
+ .inspector-overlay {
76
+ position: fixed;
77
+ pointer-events: none;
78
+ border: 3px solid var(--color-blue-500);
79
+ background: rgba(59, 130, 246, 0.1);
80
+ z-index: var(--z-inspector-overlay);
81
+ transition: all 0.1s ease;
82
+ display: none;
83
+ }
84
+
85
+ .inspector-overlay.active {
86
+ display: block;
87
+ }
88
+
89
+ .inspector-overlay.paused {
90
+ border-color: var(--color-green-500);
91
+ background: rgba(16, 185, 129, 0.1);
92
+ }
93
+
94
+ .inspector-overlay-child {
95
+ position: fixed;
96
+ pointer-events: none;
97
+ border: 1px dashed var(--color-blue-500);
98
+ background: rgba(59, 130, 246, 0.02);
99
+ z-index: var(--z-inspector-overlay);
100
+ transition: all 0.1s ease;
101
+ display: none;
102
+ opacity: 0.35;
103
+ }
104
+
105
+ .inspector-overlay-child.active {
106
+ display: block;
107
+ }
108
+
109
+ .inspector-element-tag {
110
+ transition: opacity 0.15s ease;
111
+ }
112
+
113
+ .inspector-element-tag:hover {
114
+ opacity: 0.85;
115
+ }
116
+
117
+ .inspector-element-tag:active {
118
+ opacity: 0.7;
119
+ }
120
+
121
+ /* Scrollbar styling for inspector elements */
122
+ #inspector-canvas-root ::-webkit-scrollbar {
123
+ width: 6px;
124
+ height: 6px;
125
+ }
126
+
127
+ #inspector-canvas-root ::-webkit-scrollbar-track {
128
+ background: transparent;
129
+ }
130
+
131
+ #inspector-canvas-root ::-webkit-scrollbar-thumb {
132
+ background: var(--color-gray-300);
133
+ border-radius: var(--radius-sm);
134
+ }
135
+
136
+ #inspector-canvas-root ::-webkit-scrollbar-thumb:hover {
137
+ background: var(--color-gray-400);
138
+ }
@@ -0,0 +1,151 @@
1
+ :root {
2
+ /* Spacing scale */
3
+ --spacing-0: 0;
4
+ --spacing-0-5: 0.125rem;
5
+ --spacing-1: 0.25rem;
6
+ --spacing-1-5: 0.375rem;
7
+ --spacing-2: 0.5rem;
8
+ --spacing-2-5: 0.625rem;
9
+ --spacing-3: 0.75rem;
10
+ --spacing-3-5: 0.875rem;
11
+ --spacing-4: 1rem;
12
+ --spacing-5: 1.25rem;
13
+ --spacing-6: 1.5rem;
14
+ --spacing-7: 1.75rem;
15
+ --spacing-8: 2rem;
16
+ --spacing-9: 2.25rem;
17
+ --spacing-10: 2.5rem;
18
+ --spacing-12: 3rem;
19
+ --spacing-16: 4rem;
20
+ --spacing-20: 5rem;
21
+ --spacing-24: 6rem;
22
+ --spacing-32: 8rem;
23
+
24
+ /* Border radius */
25
+ --radius-none: 0;
26
+ --radius-sm: 0.375rem;
27
+ --radius-md: 0.5rem;
28
+ --radius-lg: 0.75rem;
29
+ --radius-xl: 1rem;
30
+ --radius-2xl: 1.5rem;
31
+ --radius-3xl: 2rem;
32
+ --radius-full: 9999px;
33
+
34
+ /* Font sizes */
35
+ --text-xs: 0.75rem;
36
+ --text-sm: 0.875rem;
37
+ --text-base: 1rem;
38
+ --text-lg: 1.125rem;
39
+ --text-xl: 1.25rem;
40
+ --text-2xl: 1.5rem;
41
+ --text-3xl: 1.875rem;
42
+
43
+ /* Line heights */
44
+ --leading-none: 1;
45
+ --leading-tight: 1.25;
46
+ --leading-normal: 1.5;
47
+ --leading-relaxed: 1.75;
48
+
49
+ /* Font weights */
50
+ --font-normal: 400;
51
+ --font-medium: 500;
52
+ --font-semibold: 600;
53
+ --font-bold: 700;
54
+
55
+ /* Shadows */
56
+ --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05);
57
+ --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
58
+ --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
59
+ --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1), 0 4px 6px rgba(0, 0, 0, 0.05);
60
+ --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.1), 0 10px 10px rgba(0, 0, 0, 0.04);
61
+
62
+ /* Static colors (non-theme) */
63
+ --color-white: #ffffff;
64
+ --color-black: #000000;
65
+ --color-transparent: transparent;
66
+
67
+ /* Gray scale */
68
+ --color-gray-50: #f9fafb;
69
+ --color-gray-100: #f3f4f6;
70
+ --color-gray-200: #e5e7eb;
71
+ --color-gray-300: #d1d5db;
72
+ --color-gray-400: #9ca3af;
73
+ --color-gray-500: #6b7280;
74
+ --color-gray-600: #4b5563;
75
+ --color-gray-700: #374151;
76
+ --color-gray-800: #1f2937;
77
+ --color-gray-900: #111827;
78
+
79
+ /* Blue scale */
80
+ --color-blue-400: #60a5fa;
81
+ --color-blue-500: #3b82f6;
82
+ --color-blue-600: #2563eb;
83
+
84
+ /* Green scale */
85
+ --color-green-400: #4ade80;
86
+ --color-green-500: #22c55e;
87
+ --color-green-600: #16a34a;
88
+
89
+ /* Red scale */
90
+ --color-red-400: #f87171;
91
+ --color-red-500: #ef4444;
92
+ --color-red-600: #dc2626;
93
+
94
+ /* Z-index scale - Inspector must be above everything on the page */
95
+ --z-inspector-root: 2147483640;
96
+ --z-inspector-backdrop: 2147483641;
97
+ --z-inspector-overlay: 2147483642;
98
+ --z-inspector-controlbox: 2147483643;
99
+ --z-inspector-popover: 2147483644;
100
+ --z-inspector-tooltip: 2147483645;
101
+
102
+ /* Legacy values for backwards compatibility */
103
+ --z-dropdown: 1000;
104
+ --z-sticky: 1020;
105
+ --z-fixed: 1030;
106
+ --z-modal-backdrop: 1040;
107
+ --z-modal: 1050;
108
+ --z-popover: var(--z-inspector-popover);
109
+ --z-tooltip: var(--z-inspector-tooltip);
110
+ --z-overlay: var(--z-inspector-overlay);
111
+ --z-max: var(--z-inspector-root);
112
+
113
+ /* Transitions */
114
+ --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
115
+ --transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);
116
+ --transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
117
+
118
+ /* Typography */
119
+ --text-xs: 0.75rem; /* 12px */
120
+ --text-sm: 0.875rem; /* 14px */
121
+ --text-base: 1rem; /* 16px */
122
+ --text-lg: 1.125rem; /* 18px */
123
+ --text-xl: 1.25rem; /* 20px */
124
+
125
+ --font-normal: 400;
126
+ --font-medium: 500;
127
+ --font-semibold: 600;
128
+ --font-bold: 700;
129
+
130
+ --letter-spacing-tight: -0.01em;
131
+ --letter-spacing-normal: 0;
132
+ --letter-spacing-wide: 0.025em;
133
+ --letter-spacing-widest: 0.1em;
134
+
135
+ --font-size-xs: 0.75rem;
136
+ --font-size-sm: 0.875rem;
137
+ --font-size-base: 1rem;
138
+ --font-size-xl: 1.25rem;
139
+
140
+ --font-weight-normal: 400;
141
+ --font-weight-medium: 500;
142
+ --font-weight-semibold: 600;
143
+ --font-weight-bold: 700;
144
+
145
+ /* Font families */
146
+ --font-family-sans: 'Satoshi', -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
147
+ "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
148
+ sans-serif;
149
+ --font-family-mono: ui-monospace, "SF Mono", "Monaco", "Cascadia Mono",
150
+ "Roboto Mono", "Courier New", monospace;
151
+ }
package/src/styles.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Import this file to load inspector styles
3
+ */
4
+ import "./styles/global.css";
5
+
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Color utility functions for converting between formats
3
+ */
4
+
5
+ /**
6
+ * Convert RGB color string to HEX format
7
+ * @example rgbToHex('rgb(255, 0, 0)') => '#ff0000'
8
+ */
9
+ export function rgbToHex(rgb: string): string {
10
+ // Handle rgba as well
11
+ const match = rgb.match(/\d+/g);
12
+ if (!match || match.length < 3) return "#000000";
13
+
14
+ const r = parseInt(match[0]);
15
+ const g = parseInt(match[1]);
16
+ const b = parseInt(match[2]);
17
+
18
+ return "#" + [r, g, b].map((x) => x.toString(16).padStart(2, "0")).join("");
19
+ }
20
+
21
+ /**
22
+ * Convert HEX color to RGB format
23
+ * @example hexToRgb('#ff0000') => 'rgb(255, 0, 0)'
24
+ */
25
+ export function hexToRgb(hex: string): string {
26
+ // Remove # if present
27
+ hex = hex.replace(/^#/, "");
28
+
29
+ // Parse hex values
30
+ const r = parseInt(hex.substring(0, 2), 16);
31
+ const g = parseInt(hex.substring(2, 4), 16);
32
+ const b = parseInt(hex.substring(4, 6), 16);
33
+
34
+ return `rgb(${r}, ${g}, ${b})`;
35
+ }
36
+
37
+ /**
38
+ * Convert HEX color to RGBA object
39
+ * @example hexToRgba('#ff0000') => { r: 255, g: 0, b: 0, a: 1 }
40
+ * @example hexToRgba('#f00') => { r: 255, g: 0, b: 0, a: 1 }
41
+ * @example hexToRgba('#ff000080') => { r: 255, g: 0, b: 0, a: 0.5 }
42
+ */
43
+ export function hexToRgba(
44
+ hex: string
45
+ ): { r: number; g: number; b: number; a: number } | null {
46
+ // Remove # if present
47
+ hex = hex.replace(/^#/, "");
48
+
49
+ // Validate and normalize hex
50
+ if (/^[0-9A-Fa-f]{3}$/.test(hex)) {
51
+ // Expand 3-digit hex to 6-digit (e.g., 'f00' -> 'ff0000')
52
+ hex = hex
53
+ .split("")
54
+ .map((char) => char + char)
55
+ .join("");
56
+ } else if (!/^[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/.test(hex)) {
57
+ // Must be 6 or 8 digits
58
+ return null;
59
+ }
60
+
61
+ // Parse RGB values
62
+ const r = parseInt(hex.substring(0, 2), 16);
63
+ const g = parseInt(hex.substring(2, 4), 16);
64
+ const b = parseInt(hex.substring(4, 6), 16);
65
+
66
+ // Parse alpha if present (8-digit hex)
67
+ let a = 1;
68
+ if (hex.length === 8) {
69
+ a = parseInt(hex.substring(6, 8), 16) / 255;
70
+ }
71
+
72
+ return { r, g, b, a };
73
+ }
74
+
75
+ /**
76
+ * Convert RGBA object to HEX format
77
+ * @example rgbaToHex({ r: 255, g: 0, b: 0, a: 1 }) => '#ff0000'
78
+ * @example rgbaToHex({ r: 255, g: 0, b: 0, a: 0.5 }) => '#ff000080'
79
+ */
80
+ export function rgbaToHex(rgba: {
81
+ r: number;
82
+ g: number;
83
+ b: number;
84
+ a: number;
85
+ }): string {
86
+ const r = Math.round(Math.max(0, Math.min(255, rgba.r)));
87
+ const g = Math.round(Math.max(0, Math.min(255, rgba.g)));
88
+ const b = Math.round(Math.max(0, Math.min(255, rgba.b)));
89
+ const a = Math.max(0, Math.min(1, rgba.a));
90
+
91
+ const toHex = (n: number) => n.toString(16).padStart(2, "0");
92
+
93
+ const hex = `#${toHex(r)}${toHex(g)}${toHex(b)}`;
94
+
95
+ // Only include alpha if not fully opaque
96
+ if (a < 1) {
97
+ const alphaHex = toHex(Math.round(a * 255));
98
+ return `${hex}${alphaHex}`;
99
+ }
100
+
101
+ return hex;
102
+ }
103
+
104
+ /**
105
+ * Validate if string is a valid hex color
106
+ */
107
+ export function isValidHex(hex: string): boolean {
108
+ return /^#?[0-9A-Fa-f]{6}$/.test(hex);
109
+ }
110
+
111
+ /**
112
+ * Ensure color string has # prefix
113
+ */
114
+ export function ensureHashPrefix(color: string): string {
115
+ if (color.startsWith("#")) return color;
116
+ if (/^[0-9A-Fa-f]{6}$/.test(color)) return "#" + color;
117
+ return color;
118
+ }
119
+
120
+ /**
121
+ * Get contrasting text color (black or white) for a background color
122
+ */
123
+ export function getContrastColor(hexColor: string): string {
124
+ const color = hexColor.replace("#", "");
125
+ const r = parseInt(color.substring(0, 2), 16);
126
+ const g = parseInt(color.substring(2, 4), 16);
127
+ const b = parseInt(color.substring(4, 6), 16);
128
+
129
+ // Calculate luminance
130
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
131
+
132
+ return luminance > 0.5 ? "#000000" : "#ffffff";
133
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Element name mapping utilities
3
+ * Maps HTML tags to user-friendly names
4
+ */
5
+
6
+ // Default English values for labels
7
+ const DEFAULT_LABELS: Record<string, string> = {
8
+ elementContainer: "Container",
9
+ elementText: "Text",
10
+ elementImage: "Image",
11
+ elementButton: "Button",
12
+ elementLink: "Link",
13
+ elementInput: "Input",
14
+ elementTextArea: "TextArea",
15
+ elementHeading: "Heading",
16
+ elementParagraph: "Paragraph",
17
+ elementSection: "Section",
18
+ elementDefault: "Element",
19
+ };
20
+
21
+ // Track which labels have been warned about to avoid spam
22
+ const warnedLabels = new Set<string>();
23
+
24
+ /**
25
+ * Validates and retrieves a label with runtime warning for missing labels
26
+ */
27
+ function validateLabel(
28
+ key: string,
29
+ labels: Record<string, string> | undefined,
30
+ defaultValue: string
31
+ ): string {
32
+ if (!labels || !labels[key]) {
33
+ // Only warn once per missing label
34
+ if (!warnedLabels.has(key)) {
35
+ console.warn(
36
+ `[Inspector] Missing label: "${key}". Using default: "${defaultValue}". ` +
37
+ `Please add this label to your InspectorLabels configuration.`
38
+ );
39
+ warnedLabels.add(key);
40
+ }
41
+ return defaultValue;
42
+ }
43
+ return labels[key];
44
+ }
45
+
46
+ export const getElementDisplayName = (
47
+ element: HTMLElement | Element,
48
+ labels?: Record<string, string>
49
+ ): string => {
50
+ if (!element || !element.tagName) {
51
+ return validateLabel(
52
+ "elementDefault",
53
+ labels,
54
+ DEFAULT_LABELS.elementDefault
55
+ );
56
+ }
57
+
58
+ const tagName = element.tagName.toLowerCase();
59
+
60
+ // Map HTML tags to label keys
61
+ const tagToLabelKey: Record<string, string> = {
62
+ div: "elementContainer",
63
+ span: "elementText",
64
+ img: "elementImage",
65
+ button: "elementButton",
66
+ a: "elementLink",
67
+ input: "elementInput",
68
+ textarea: "elementTextArea",
69
+ h1: "elementHeading",
70
+ h2: "elementHeading",
71
+ h3: "elementHeading",
72
+ h4: "elementHeading",
73
+ h5: "elementHeading",
74
+ h6: "elementHeading",
75
+ p: "elementParagraph",
76
+ section: "elementSection",
77
+ };
78
+
79
+ // Special cases that don't need labels
80
+ if (tagName === "svg" || tagName === "path") {
81
+ return "Icon";
82
+ }
83
+
84
+ const labelKey = tagToLabelKey[tagName];
85
+ if (labelKey) {
86
+ return validateLabel(labelKey, labels, DEFAULT_LABELS[labelKey]);
87
+ }
88
+
89
+ return validateLabel("elementDefault", labels, DEFAULT_LABELS.elementDefault);
90
+ };
91
+
92
+ export const getElementLabel = (
93
+ element: HTMLElement | Element,
94
+ labels?: Record<string, string>
95
+ ): string => {
96
+ if (!element || !element.tagName) {
97
+ return "Element";
98
+ }
99
+
100
+ const displayName = getElementDisplayName(element, labels);
101
+ const tagName = element.tagName.toLowerCase();
102
+ return `${displayName} (${tagName})`;
103
+ };
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Element detection utilities for determining which style sections to show
3
+ */
4
+
5
+ /**
6
+ * Determine if a specific section should be shown for an element
7
+ */
8
+ export function shouldShowSection(
9
+ element: HTMLElement,
10
+ section: string
11
+ ): boolean {
12
+ const tagName = element.tagName.toLowerCase();
13
+
14
+ switch (section) {
15
+ case "layout":
16
+ // Show for all elements
17
+ return true;
18
+
19
+ case "display":
20
+ // Show for all elements
21
+ return true;
22
+
23
+ case "text":
24
+ // Hide for img, input, textarea, video, audio, canvas
25
+ if (
26
+ ["img", "input", "textarea", "video", "audio", "canvas", "svg"].includes(
27
+ tagName
28
+ )
29
+ ) {
30
+ return false;
31
+ }
32
+ // Show if element has text content or can contain text
33
+ return true;
34
+
35
+ case "image":
36
+ // Only show for img elements
37
+ return tagName === "img";
38
+
39
+ case "border":
40
+ // Show for all elements
41
+ return true;
42
+
43
+ case "spacing":
44
+ // Show for all elements
45
+ return true;
46
+
47
+ default:
48
+ return true;
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Get element type for conditional rendering
54
+ */
55
+ export function getElementType(element: HTMLElement): string {
56
+ return element.tagName.toLowerCase();
57
+ }
58
+
59
+ /**
60
+ * Check if element is a specific type
61
+ */
62
+ export function isElementType(
63
+ element: HTMLElement,
64
+ type: string
65
+ ): boolean {
66
+ return element.tagName.toLowerCase() === type;
67
+ }
68
+
69
+ /**
70
+ * Check if element can have text content
71
+ */
72
+ export function canHaveTextContent(element: HTMLElement): boolean {
73
+ const tagName = element.tagName.toLowerCase();
74
+ return !["img", "input", "video", "audio", "canvas"].includes(tagName);
75
+ }
76
+
77
+ /**
78
+ * Check if element is an image
79
+ */
80
+ export function isImage(element: HTMLElement): boolean {
81
+ return element.tagName.toLowerCase() === "img";
82
+ }
83
+
84
+ /**
85
+ * Check if element is an anchor tag
86
+ */
87
+ export function isAnchor(element: HTMLElement): boolean {
88
+ return element.tagName.toLowerCase() === "a";
89
+ }
90
+