@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,381 @@
1
+ /**
2
+ * TextSection - Color, Font Size, Font Weight, Font Family, Text Align
3
+ */
4
+
5
+ import type { StyleChanges } from "@promakeai/inspector-types";
6
+ import { ColorPicker } from "./ColorPicker";
7
+ import {
8
+ Select,
9
+ SelectContent,
10
+ SelectItem,
11
+ SelectTrigger,
12
+ SelectValue,
13
+ } from "../ui/select";
14
+ import { Button } from "../ui/button";
15
+ import { AlignLeft, AlignCenter, AlignRight, AlignJustify, RotateCcw } from "lucide-react";
16
+ import { useInspectorStore } from "../../store/useInspectorStore";
17
+ import cssStyles from "./shared.module.css";
18
+ import { cn } from "@/lib/utils";
19
+
20
+ interface TextSectionProps {
21
+ styles: StyleChanges;
22
+ onChange: (property: keyof StyleChanges, value: string) => void;
23
+ originalStyles: StyleChanges;
24
+ onResetProperty: (property: keyof StyleChanges) => void;
25
+ }
26
+
27
+ const FONT_FAMILIES = [
28
+ { label: "Sans", value: "ui-sans-serif, system-ui, sans-serif" },
29
+ { label: "Serif", value: "ui-serif, Georgia, serif" },
30
+ { label: "Mono", value: "ui-monospace, monospace" },
31
+ ];
32
+
33
+ const TEXT_ALIGNS = [
34
+ { label: "Left", value: "left", Icon: AlignLeft },
35
+ { label: "Center", value: "center", Icon: AlignCenter },
36
+ { label: "Right", value: "right", Icon: AlignRight },
37
+ { label: "Justify", value: "justify", Icon: AlignJustify },
38
+ ];
39
+
40
+ export function TextSection({ styles, onChange, originalStyles, onResetProperty }: TextSectionProps) {
41
+ const { labels, theme } = useInspectorStore();
42
+
43
+ const FONT_SIZES = [
44
+ { label: labels.fontSizeXS || "XS", value: "0.75rem" },
45
+ { label: labels.fontSizeSM || "SM", value: "0.875rem" },
46
+ { label: labels.fontSizeBase || "Base", value: "1rem" },
47
+ { label: labels.fontSizeLG || "LG", value: "1.125rem" },
48
+ { label: labels.fontSizeXL || "XL", value: "1.25rem" },
49
+ { label: labels.fontSize2XL || "2XL", value: "1.5rem" },
50
+ { label: labels.fontSize3XL || "3XL", value: "1.875rem" },
51
+ { label: labels.fontSize4XL || "4XL", value: "2.25rem" },
52
+ { label: labels.fontSize5XL || "5XL", value: "3rem" },
53
+ ];
54
+
55
+ const FONT_WEIGHTS = [
56
+ { label: labels.fontWeightThin || "Thin", value: "100" },
57
+ { label: labels.fontWeightExtralight || "Extralight", value: "200" },
58
+ { label: labels.fontWeightNormal || "Normal", value: "400" },
59
+ { label: labels.fontWeightMedium || "Medium", value: "500" },
60
+ { label: labels.fontWeightSemibold || "Semibold", value: "600" },
61
+ { label: labels.fontWeightBold || "Bold", value: "700" },
62
+ { label: labels.fontWeightExtrabold || "Extrabold", value: "800" },
63
+ { label: labels.fontWeightBlack || "Black", value: "900" },
64
+ ];
65
+
66
+ const TEXT_DECORATIONS = [
67
+ { label: labels.textDecorationNone || "None", value: "none" },
68
+ { label: labels.textDecorationUnderline || "Underline", value: "underline" },
69
+ { label: labels.textDecorationLineThrough || "Line Through", value: "line-through" },
70
+ { label: labels.textDecorationOverline || "Overline", value: "overline" },
71
+ ];
72
+ return (
73
+ <div className={cssStyles.section}>
74
+ {/* Color and Font Size - Side by side */}
75
+ <div className={cssStyles.grid2}>
76
+ <ColorPicker
77
+ label={labels.colorLabel || "Color"}
78
+ value={styles.color || "#000000"}
79
+ onChange={(value) => onChange("color", value)}
80
+ originalValue={originalStyles.color}
81
+ onReset={() => onResetProperty("color")}
82
+ />
83
+
84
+ {/* Font Size */}
85
+ <div>
86
+ <div className={cssStyles.labelContainer}>
87
+ <label className={cssStyles.label} style={{ color: theme.textColor }}>
88
+ {labels.fontSizeLabel || "Font Size"}
89
+ </label>
90
+ {styles.fontSize !== originalStyles.fontSize && (
91
+ <button
92
+ type="button"
93
+ onClick={() => onResetProperty("fontSize")}
94
+ className={cssStyles.resetIcon}
95
+ style={{ color: theme.secondaryTextColor }}
96
+ title="Reset to original"
97
+ >
98
+ <RotateCcw size={12} />
99
+ </button>
100
+ )}
101
+ </div>
102
+ <div
103
+ className={cssStyles.inputContainer}
104
+ style={{
105
+ backgroundColor: theme.inputBackgroundColor,
106
+ borderColor: theme.inputBorderColor,
107
+ }}
108
+ >
109
+ <Select
110
+ value={styles.fontSize || "1rem"}
111
+ onValueChange={(value) => onChange("fontSize", value)}
112
+ >
113
+ <SelectTrigger
114
+ className={cssStyles.input}
115
+ style={{
116
+ backgroundColor: "transparent",
117
+ color: theme.inputTextColor,
118
+ }}
119
+ size="sm"
120
+ >
121
+ <SelectValue />
122
+ </SelectTrigger>
123
+ <SelectContent
124
+ style={{
125
+ backgroundColor: theme.backgroundColor,
126
+ borderColor: theme.borderColor,
127
+ }}
128
+ >
129
+ {FONT_SIZES.map((size) => (
130
+ <SelectItem
131
+ key={size.value}
132
+ value={size.value}
133
+ style={{
134
+ color: theme.textColor,
135
+ }}
136
+ >
137
+ {size.label}
138
+ </SelectItem>
139
+ ))}
140
+ </SelectContent>
141
+ </Select>
142
+ </div>
143
+ </div>
144
+ </div>
145
+
146
+ {/* Font Weight and Text Decoration - Side by side */}
147
+ <div className={cssStyles.grid2}>
148
+ {/* Font Weight */}
149
+ <div>
150
+ <div className={cssStyles.labelContainer}>
151
+ <label className={cssStyles.label} style={{ color: theme.textColor }}>
152
+ {labels.fontWeightLabel || "Font Weight"}
153
+ </label>
154
+ {styles.fontWeight !== originalStyles.fontWeight && (
155
+ <button
156
+ type="button"
157
+ onClick={() => onResetProperty("fontWeight")}
158
+ className={cssStyles.resetIcon}
159
+ style={{ color: theme.secondaryTextColor }}
160
+ title="Reset to original"
161
+ >
162
+ <RotateCcw size={12} />
163
+ </button>
164
+ )}
165
+ </div>
166
+ <div
167
+ className={cssStyles.inputContainer}
168
+ style={{
169
+ backgroundColor: theme.inputBackgroundColor,
170
+ borderColor: theme.inputBorderColor,
171
+ }}
172
+ >
173
+ <Select
174
+ value={styles.fontWeight || "400"}
175
+ onValueChange={(value) => onChange("fontWeight", value)}
176
+ >
177
+ <SelectTrigger
178
+ className={cssStyles.input}
179
+ style={{
180
+ backgroundColor: "transparent",
181
+ color: theme.inputTextColor,
182
+ }}
183
+ size="sm"
184
+ >
185
+ <SelectValue />
186
+ </SelectTrigger>
187
+ <SelectContent
188
+ style={{
189
+ backgroundColor: theme.backgroundColor,
190
+ borderColor: theme.borderColor,
191
+ }}
192
+ >
193
+ {FONT_WEIGHTS.map((weight) => (
194
+ <SelectItem
195
+ key={weight.value}
196
+ value={weight.value}
197
+ style={{
198
+ color: theme.textColor,
199
+ }}
200
+ >
201
+ {weight.label}
202
+ </SelectItem>
203
+ ))}
204
+ </SelectContent>
205
+ </Select>
206
+ </div>
207
+ </div>
208
+
209
+ {/* Text Decoration */}
210
+ <div>
211
+ <div className={cssStyles.labelContainer}>
212
+ <label className={cssStyles.label} style={{ color: theme.textColor }}>
213
+ {labels.textDecorationLabel || "Text Decoration"}
214
+ </label>
215
+ {styles.textDecoration !== originalStyles.textDecoration && (
216
+ <button
217
+ type="button"
218
+ onClick={() => onResetProperty("textDecoration")}
219
+ className={cssStyles.resetIcon}
220
+ style={{ color: theme.secondaryTextColor }}
221
+ title="Reset to original"
222
+ >
223
+ <RotateCcw size={12} />
224
+ </button>
225
+ )}
226
+ </div>
227
+ <div
228
+ className={cssStyles.inputContainer}
229
+ style={{
230
+ backgroundColor: theme.inputBackgroundColor,
231
+ borderColor: theme.inputBorderColor,
232
+ }}
233
+ >
234
+ <Select
235
+ value={styles.textDecoration || "none"}
236
+ onValueChange={(value) => onChange("textDecoration", value)}
237
+ >
238
+ <SelectTrigger
239
+ className={cssStyles.input}
240
+ style={{
241
+ backgroundColor: "transparent",
242
+ color: theme.inputTextColor,
243
+ }}
244
+ size="sm"
245
+ >
246
+ <SelectValue />
247
+ </SelectTrigger>
248
+ <SelectContent
249
+ style={{
250
+ backgroundColor: theme.backgroundColor,
251
+ borderColor: theme.borderColor,
252
+ }}
253
+ >
254
+ {TEXT_DECORATIONS.map((decoration) => (
255
+ <SelectItem
256
+ key={decoration.value}
257
+ value={decoration.value}
258
+ style={{
259
+ color: theme.textColor,
260
+ }}
261
+ >
262
+ {decoration.label}
263
+ </SelectItem>
264
+ ))}
265
+ </SelectContent>
266
+ </Select>
267
+ </div>
268
+ </div>
269
+ </div>
270
+
271
+ {/* Font Family */}
272
+ <div>
273
+ <div className={cssStyles.labelContainer}>
274
+ <label className={cssStyles.label} style={{ color: theme.textColor }}>
275
+ {labels.fontFamilyLabel || "Font Family"}
276
+ </label>
277
+ {styles.fontFamily !== originalStyles.fontFamily && (
278
+ <button
279
+ type="button"
280
+ onClick={() => onResetProperty("fontFamily")}
281
+ className={cssStyles.resetIcon}
282
+ style={{ color: theme.secondaryTextColor }}
283
+ title="Reset to original"
284
+ >
285
+ <RotateCcw size={12} />
286
+ </button>
287
+ )}
288
+ </div>
289
+ <div
290
+ className={cn(
291
+ cssStyles.inputContainer,
292
+ cssStyles.buttonGroupContainer
293
+ )}
294
+ style={{
295
+ backgroundColor: theme.inputBackgroundColor,
296
+ borderColor: theme.inputBorderColor,
297
+ }}
298
+ >
299
+ <div className={cn(cssStyles.flexRow, cssStyles.tabButtons)}>
300
+ {FONT_FAMILIES.map((family) => (
301
+ <Button
302
+ key={family.value}
303
+ variant={
304
+ styles.fontFamily === family.value ? "default" : "ghost"
305
+ }
306
+ onClick={() => onChange("fontFamily", family.value)}
307
+ className={cssStyles.fontButton}
308
+ style={{
309
+ backgroundColor:
310
+ styles.fontFamily === family.value
311
+ ? theme.buttonColor
312
+ : "transparent",
313
+ color:
314
+ styles.fontFamily === family.value
315
+ ? theme.buttonTextColor
316
+ : theme.textColor,
317
+ }}
318
+ >
319
+ {family.label}
320
+ </Button>
321
+ ))}
322
+ </div>
323
+ </div>
324
+ </div>
325
+
326
+ {/* Text Align */}
327
+ <div>
328
+ <div className={cssStyles.labelContainer}>
329
+ <label className={cssStyles.label} style={{ color: theme.textColor }}>
330
+ {labels.textAlignLabel || "Text Align"}
331
+ </label>
332
+ {styles.textAlign !== originalStyles.textAlign && (
333
+ <button
334
+ type="button"
335
+ onClick={() => onResetProperty("textAlign")}
336
+ className={cssStyles.resetIcon}
337
+ style={{ color: theme.secondaryTextColor }}
338
+ title="Reset to original"
339
+ >
340
+ <RotateCcw size={12} />
341
+ </button>
342
+ )}
343
+ </div>
344
+ <div
345
+ className={cn(
346
+ cssStyles.inputContainer,
347
+ cssStyles.buttonGroupContainer
348
+ )}
349
+ style={{
350
+ backgroundColor: theme.inputBackgroundColor,
351
+ borderColor: theme.inputBorderColor,
352
+ }}
353
+ >
354
+ <div className={cssStyles.grid4}>
355
+ {TEXT_ALIGNS.map((align) => (
356
+ <Button
357
+ key={align.value}
358
+ variant={styles.textAlign === align.value ? "default" : "ghost"}
359
+ onClick={() => onChange("textAlign", align.value)}
360
+ title={align.label}
361
+ className={cssStyles.alignButton}
362
+ style={{
363
+ backgroundColor:
364
+ styles.textAlign === align.value
365
+ ? theme.buttonColor
366
+ : "transparent",
367
+ color:
368
+ styles.textAlign === align.value
369
+ ? theme.buttonTextColor
370
+ : theme.textColor,
371
+ }}
372
+ >
373
+ <align.Icon className={cssStyles.alignIcon} />
374
+ </Button>
375
+ ))}
376
+ </div>
377
+ </div>
378
+ </div>
379
+ </div>
380
+ );
381
+ }
@@ -0,0 +1,133 @@
1
+ .container {
2
+ flex: 1;
3
+ display: flex;
4
+ flex-direction: column;
5
+ min-height: 0;
6
+ max-height: 100%;
7
+ overflow: hidden;
8
+ box-sizing: border-box;
9
+ }
10
+
11
+ .scrollArea {
12
+ overflow-y: auto;
13
+ overflow-x: hidden;
14
+ padding-top: 0;
15
+ padding-bottom: 0;
16
+ display: flex;
17
+ flex-direction: column;
18
+ max-height: 40vh !important;
19
+ gap: 0;
20
+ }
21
+
22
+ /* Custom scrollbar for style editor */
23
+ .scrollArea::-webkit-scrollbar {
24
+ width: 3px;
25
+ }
26
+
27
+ .scrollArea::-webkit-scrollbar-track {
28
+ background: transparent;
29
+ }
30
+
31
+ .scrollArea::-webkit-scrollbar-thumb {
32
+ background: var(--color-border);
33
+ border-radius: var(--radius-full);
34
+ }
35
+
36
+ .scrollArea::-webkit-scrollbar-thumb:hover {
37
+ background: var(--color-muted);
38
+ }
39
+
40
+ .collapsibleTrigger {
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: space-between;
44
+ padding: var(--spacing-3) var(--spacing-2);
45
+ font-family: "Satoshi", var(--font-family-sans);
46
+ font-weight: var(--font-medium);
47
+ border-radius: var(--radius-md);
48
+ cursor: pointer;
49
+ transition: all var(--transition-fast);
50
+ }
51
+
52
+ .collapsibleTrigger:hover {
53
+ opacity: 0.95;
54
+ }
55
+
56
+ .collapsibleContent {
57
+ padding: var(--spacing-1) var(--spacing-1-5);
58
+ padding-top: var(--spacing-3);
59
+ padding-bottom: var(--spacing-1);
60
+ border-bottom-left-radius: var(--radius-md);
61
+ border-bottom-right-radius: var(--radius-md);
62
+ }
63
+
64
+ .chevron {
65
+ width: 1rem;
66
+ height: 1rem;
67
+ flex-shrink: 0;
68
+ transition: transform var(--transition-fast);
69
+ }
70
+
71
+ .chevronOpen {
72
+ transform: rotate(180deg);
73
+ }
74
+
75
+ .actionsContainer {
76
+ flex-shrink: 0;
77
+ padding-top: var(--spacing-1-5);
78
+ }
79
+
80
+ .statusIndicator {
81
+ font-size: var(--text-xs);
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: flex-end;
85
+ gap: var(--spacing-1);
86
+ margin-bottom: var(--spacing-2);
87
+ }
88
+
89
+ .statusIcon {
90
+ width: var(--spacing-3);
91
+ height: var(--spacing-3);
92
+ fill: currentColor;
93
+ }
94
+
95
+ .buttonGroup {
96
+ display: flex;
97
+ gap: var(--spacing-2);
98
+ }
99
+
100
+ .resetButton {
101
+ flex-shrink: 0;
102
+ }
103
+
104
+ .applyButton {
105
+ flex: 1;
106
+ }
107
+
108
+ .savingSpinner {
109
+ width: var(--spacing-3);
110
+ height: var(--spacing-3);
111
+ border: 2px solid currentColor;
112
+ border-top-color: transparent;
113
+ border-radius: var(--radius-full);
114
+ animation: spin 1s linear infinite;
115
+ }
116
+
117
+ .buttonContent {
118
+ display: flex;
119
+ align-items: center;
120
+ justify-content: center;
121
+ gap: var(--spacing-1-5);
122
+ }
123
+
124
+ .buttonIcon {
125
+ width: var(--spacing-4);
126
+ height: var(--spacing-4);
127
+ }
128
+
129
+ @keyframes spin {
130
+ to {
131
+ transform: rotate(360deg);
132
+ }
133
+ }