@moontra/moonui-pro 2.8.10 → 2.8.11

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.
package/dist/index.mjs CHANGED
@@ -4044,7 +4044,7 @@ var me = t.forwardRef((r2, o) => {
4044
4044
  var e;
4045
4045
  return Array.from(((e = I.current) == null ? void 0 : e.querySelectorAll(ce)) || []);
4046
4046
  }
4047
- function X19(e) {
4047
+ function X20(e) {
4048
4048
  let s = V()[e];
4049
4049
  s && E.setState("value", s.getAttribute(T));
4050
4050
  }
@@ -4059,10 +4059,10 @@ var me = t.forwardRef((r2, o) => {
4059
4059
  s = e > 0 ? we(s, N) : De(s, N), i = s == null ? void 0 : s.querySelector(ce);
4060
4060
  i ? E.setState("value", i.getAttribute(T)) : Q(e);
4061
4061
  }
4062
- let oe = () => X19(V().length - 1), ie3 = (e) => {
4062
+ let oe = () => X20(V().length - 1), ie3 = (e) => {
4063
4063
  e.preventDefault(), e.metaKey ? oe() : e.altKey ? re(1) : Q(1);
4064
4064
  }, se = (e) => {
4065
- e.preventDefault(), e.metaKey ? X19(0) : e.altKey ? re(-1) : Q(-1);
4065
+ e.preventDefault(), e.metaKey ? X20(0) : e.altKey ? re(-1) : Q(-1);
4066
4066
  };
4067
4067
  return t.createElement(Primitive2.div, { ref: o, tabIndex: -1, ...O, "cmdk-root": "", onKeyDown: (e) => {
4068
4068
  var s;
@@ -4089,7 +4089,7 @@ var me = t.forwardRef((r2, o) => {
4089
4089
  break;
4090
4090
  }
4091
4091
  case "Home": {
4092
- e.preventDefault(), X19(0);
4092
+ e.preventDefault(), X20(0);
4093
4093
  break;
4094
4094
  }
4095
4095
  case "End": {
@@ -50283,53 +50283,78 @@ var EditorColorPicker = ({
50283
50283
  onColorSelect,
50284
50284
  currentColor = "#000000"
50285
50285
  }) => {
50286
- return /* @__PURE__ */ jsx(
50287
- MoonUIColorPickerPro,
50288
- {
50289
- value: currentColor,
50290
- onChange: onColorSelect,
50291
- showInput: true,
50292
- showPresets: true,
50293
- size: "sm",
50294
- presets: [
50295
- "#000000",
50296
- "#ffffff",
50297
- "#ff0000",
50298
- "#00ff00",
50299
- "#0000ff",
50300
- "#ffff00",
50301
- "#ff00ff",
50302
- "#00ffff",
50303
- "#ff8800",
50304
- "#8800ff",
50305
- "#88ff00",
50306
- "#0088ff",
50307
- "#ff0088",
50308
- "#00ff88",
50309
- "#888888",
50310
- "#f87171",
50311
- "#fb923c",
50312
- "#fbbf24",
50313
- "#facc15",
50314
- "#a3e635",
50315
- "#4ade80",
50316
- "#34d399",
50317
- "#2dd4bf",
50318
- "#22d3ee",
50319
- "#38bdf8",
50320
- "#60a5fa",
50321
- "#818cf8",
50322
- "#a78bfa",
50323
- "#c084fc",
50324
- "#e879f9",
50325
- "#f472b6",
50326
- "#fb7185",
50327
- "#f43f5e",
50328
- "#ef4444",
50329
- "#dc2626"
50330
- ]
50331
- }
50332
- );
50286
+ const [showAdvanced, setShowAdvanced] = t__default.useState(false);
50287
+ const quickColors = [
50288
+ "#000000",
50289
+ // Black
50290
+ "#ef4444",
50291
+ // Red
50292
+ "#f59e0b",
50293
+ // Orange
50294
+ "#10b981",
50295
+ // Green
50296
+ "#3b82f6",
50297
+ // Blue
50298
+ "#8b5cf6",
50299
+ // Purple
50300
+ "#6b7280",
50301
+ // Gray
50302
+ "#ec4899"
50303
+ // Pink
50304
+ ];
50305
+ if (showAdvanced) {
50306
+ return /* @__PURE__ */ jsxs("div", { className: "p-4 w-64", children: [
50307
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
50308
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Choose Color" }),
50309
+ /* @__PURE__ */ jsx(
50310
+ MoonUIButtonPro,
50311
+ {
50312
+ size: "sm",
50313
+ variant: "ghost",
50314
+ onClick: () => setShowAdvanced(false),
50315
+ children: "Back"
50316
+ }
50317
+ )
50318
+ ] }),
50319
+ /* @__PURE__ */ jsx(
50320
+ MoonUIColorPickerPro,
50321
+ {
50322
+ value: currentColor,
50323
+ onChange: (color) => {
50324
+ onColorSelect(color);
50325
+ setShowAdvanced(false);
50326
+ },
50327
+ showInput: true,
50328
+ showPresets: false,
50329
+ size: "sm"
50330
+ }
50331
+ )
50332
+ ] });
50333
+ }
50334
+ return /* @__PURE__ */ jsx("div", { className: "p-3 w-36", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
50335
+ quickColors.map((color) => /* @__PURE__ */ jsx(
50336
+ "button",
50337
+ {
50338
+ onClick: () => onColorSelect(color),
50339
+ className: cn(
50340
+ "w-10 h-10 rounded-md border-2 hover:scale-110 transition-transform",
50341
+ currentColor === color ? "border-primary" : "border-transparent"
50342
+ ),
50343
+ style: { backgroundColor: color },
50344
+ title: color
50345
+ },
50346
+ color
50347
+ )),
50348
+ /* @__PURE__ */ jsx(
50349
+ "button",
50350
+ {
50351
+ onClick: () => setShowAdvanced(true),
50352
+ className: "w-10 h-10 rounded-md border-2 border-dashed border-muted-foreground/50 hover:border-primary transition-colors flex items-center justify-center",
50353
+ title: "More colors",
50354
+ children: /* @__PURE__ */ jsx(Palette, { className: "w-5 h-5 text-muted-foreground" })
50355
+ }
50356
+ )
50357
+ ] }) });
50333
50358
  };
50334
50359
  var ToolbarButton = ({
50335
50360
  active,
@@ -50434,6 +50459,8 @@ function RichTextEditor({
50434
50459
  const [isTyping, setIsTyping] = useState(false);
50435
50460
  const typingIntervalRef = useRef(null);
50436
50461
  const [currentAction, setCurrentAction] = useState("");
50462
+ const [remainingText, setRemainingText] = useState("");
50463
+ const isTypingRef = useRef(false);
50437
50464
  const [isSourceView, setIsSourceView] = useState(false);
50438
50465
  const [sourceContent, setSourceContent] = useState("");
50439
50466
  const [currentTextColor, setCurrentTextColor] = useState("#000000");
@@ -50451,6 +50478,20 @@ function RichTextEditor({
50451
50478
  }
50452
50479
  };
50453
50480
  }, []);
50481
+ const stopTyping = () => {
50482
+ if (typingIntervalRef.current) {
50483
+ clearTimeout(typingIntervalRef.current);
50484
+ typingIntervalRef.current = null;
50485
+ }
50486
+ setIsTyping(false);
50487
+ isTypingRef.current = false;
50488
+ setTypingText("");
50489
+ setRemainingText("");
50490
+ toast({
50491
+ title: "AI typing stopped",
50492
+ description: "The AI response was interrupted."
50493
+ });
50494
+ };
50454
50495
  const slashCommands = [
50455
50496
  {
50456
50497
  id: "rewrite",
@@ -50732,6 +50773,7 @@ function RichTextEditor({
50732
50773
  processingToast.dismiss();
50733
50774
  if (result) {
50734
50775
  setIsTyping(true);
50776
+ isTypingRef.current = true;
50735
50777
  setTypingText("");
50736
50778
  if (selectedText) {
50737
50779
  editor.chain().focus().deleteSelection().run();
@@ -50739,19 +50781,24 @@ function RichTextEditor({
50739
50781
  let currentIndex = 0;
50740
50782
  const typeSpeed = 30;
50741
50783
  const typeNextChar = () => {
50742
- if (currentIndex < result.length) {
50784
+ if (currentIndex < result.length && isTypingRef.current) {
50743
50785
  const nextChar = result[currentIndex];
50744
50786
  setTypingText((prev) => prev + nextChar);
50745
50787
  editor.chain().focus().insertContent(nextChar).run();
50746
50788
  currentIndex++;
50789
+ setRemainingText(result.substring(currentIndex));
50747
50790
  typingIntervalRef.current = setTimeout(typeNextChar, typeSpeed);
50748
50791
  } else {
50749
50792
  setIsTyping(false);
50793
+ isTypingRef.current = false;
50750
50794
  setTypingText("");
50751
- toast({
50752
- title: "AI action completed",
50753
- description: "Your text has been updated successfully."
50754
- });
50795
+ setRemainingText("");
50796
+ if (currentIndex >= result.length) {
50797
+ toast({
50798
+ title: "AI action completed",
50799
+ description: "Your text has been updated successfully."
50800
+ });
50801
+ }
50755
50802
  }
50756
50803
  };
50757
50804
  typeNextChar();
@@ -51301,6 +51348,17 @@ function RichTextEditor({
51301
51348
  ]
51302
51349
  }
51303
51350
  ) }),
51351
+ isTyping && /* @__PURE__ */ jsx(
51352
+ MoonUIButtonPro,
51353
+ {
51354
+ variant: "destructive",
51355
+ size: "sm",
51356
+ className: "h-8 px-2",
51357
+ onClick: stopTyping,
51358
+ title: "Stop AI typing",
51359
+ children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
51360
+ }
51361
+ ),
51304
51362
  /* @__PURE__ */ jsxs(MoonUIDropdownMenuContentPro, { className: "w-64", children: [
51305
51363
  /* @__PURE__ */ jsxs("div", { className: "px-2 py-1.5 text-xs font-semibold text-muted-foreground flex items-center gap-2", children: [
51306
51364
  /* @__PURE__ */ jsx(Wand2, { className: "w-3 h-3" }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moontra/moonui-pro",
3
- "version": "2.8.10",
3
+ "version": "2.8.11",
4
4
  "description": "Premium React components for MoonUI - Advanced UI library with 50+ pro components including performance, interactive, and gesture components",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -73,7 +73,8 @@ import {
73
73
  Heart,
74
74
  GraduationCap,
75
75
  Zap,
76
- Lightbulb
76
+ Lightbulb,
77
+ X
77
78
  } from 'lucide-react';
78
79
  import { cn } from '../../lib/utils';
79
80
  import { Button } from '../ui/button';
@@ -218,23 +219,71 @@ const EditorColorPicker = ({
218
219
  onColorSelect: (color: string) => void;
219
220
  currentColor?: string;
220
221
  }) => {
222
+ const [showAdvanced, setShowAdvanced] = React.useState(false);
223
+
224
+ // Quick colors - 3x3 grid of 8 colors + 1 advanced button
225
+ const quickColors = [
226
+ '#000000', // Black
227
+ '#ef4444', // Red
228
+ '#f59e0b', // Orange
229
+ '#10b981', // Green
230
+ '#3b82f6', // Blue
231
+ '#8b5cf6', // Purple
232
+ '#6b7280', // Gray
233
+ '#ec4899', // Pink
234
+ ];
235
+
236
+ if (showAdvanced) {
237
+ return (
238
+ <div className="p-4 w-64">
239
+ <div className="flex items-center justify-between mb-3">
240
+ <span className="text-sm font-medium">Choose Color</span>
241
+ <Button
242
+ size="sm"
243
+ variant="ghost"
244
+ onClick={() => setShowAdvanced(false)}
245
+ >
246
+ Back
247
+ </Button>
248
+ </div>
249
+ <ColorPicker
250
+ value={currentColor}
251
+ onChange={(color) => {
252
+ onColorSelect(color);
253
+ setShowAdvanced(false);
254
+ }}
255
+ showInput={true}
256
+ showPresets={false}
257
+ size="sm"
258
+ />
259
+ </div>
260
+ );
261
+ }
262
+
221
263
  return (
222
- <ColorPicker
223
- value={currentColor}
224
- onChange={onColorSelect}
225
- showInput={true}
226
- showPresets={true}
227
- size="sm"
228
- presets={[
229
- '#000000', '#ffffff', '#ff0000', '#00ff00', '#0000ff',
230
- '#ffff00', '#ff00ff', '#00ffff', '#ff8800', '#8800ff',
231
- '#88ff00', '#0088ff', '#ff0088', '#00ff88', '#888888',
232
- '#f87171', '#fb923c', '#fbbf24', '#facc15', '#a3e635',
233
- '#4ade80', '#34d399', '#2dd4bf', '#22d3ee', '#38bdf8',
234
- '#60a5fa', '#818cf8', '#a78bfa', '#c084fc', '#e879f9',
235
- '#f472b6', '#fb7185', '#f43f5e', '#ef4444', '#dc2626',
236
- ]}
237
- />
264
+ <div className="p-3 w-36">
265
+ <div className="grid grid-cols-3 gap-2">
266
+ {quickColors.map((color) => (
267
+ <button
268
+ key={color}
269
+ onClick={() => onColorSelect(color)}
270
+ className={cn(
271
+ "w-10 h-10 rounded-md border-2 hover:scale-110 transition-transform",
272
+ currentColor === color ? "border-primary" : "border-transparent"
273
+ )}
274
+ style={{ backgroundColor: color }}
275
+ title={color}
276
+ />
277
+ ))}
278
+ <button
279
+ onClick={() => setShowAdvanced(true)}
280
+ className="w-10 h-10 rounded-md border-2 border-dashed border-muted-foreground/50 hover:border-primary transition-colors flex items-center justify-center"
281
+ title="More colors"
282
+ >
283
+ <Palette className="w-5 h-5 text-muted-foreground" />
284
+ </button>
285
+ </div>
286
+ </div>
238
287
  );
239
288
  };
240
289
 
@@ -379,6 +428,8 @@ export function RichTextEditor({
379
428
  const [isTyping, setIsTyping] = useState(false);
380
429
  const typingIntervalRef = useRef<NodeJS.Timeout | null>(null);
381
430
  const [currentAction, setCurrentAction] = useState('');
431
+ const [remainingText, setRemainingText] = useState(''); // To store remaining text when stopped
432
+ const isTypingRef = useRef(false); // Ref to track typing state in closure
382
433
  const [isSourceView, setIsSourceView] = useState(false);
383
434
  const [sourceContent, setSourceContent] = useState('');
384
435
  const [currentTextColor, setCurrentTextColor] = useState('#000000');
@@ -399,6 +450,22 @@ export function RichTextEditor({
399
450
  }
400
451
  };
401
452
  }, []);
453
+
454
+ // Stop typing function
455
+ const stopTyping = () => {
456
+ if (typingIntervalRef.current) {
457
+ clearTimeout(typingIntervalRef.current);
458
+ typingIntervalRef.current = null;
459
+ }
460
+ setIsTyping(false);
461
+ isTypingRef.current = false;
462
+ setTypingText('');
463
+ setRemainingText('');
464
+ toast({
465
+ title: "AI typing stopped",
466
+ description: "The AI response was interrupted.",
467
+ });
468
+ };
402
469
 
403
470
  // Slash commands tanımları
404
471
  const slashCommands: SlashCommand[] = [
@@ -699,6 +766,7 @@ export function RichTextEditor({
699
766
  if (result) {
700
767
  // Start typewriter effect
701
768
  setIsTyping(true);
769
+ isTypingRef.current = true;
702
770
  setTypingText('');
703
771
 
704
772
  if (selectedText) {
@@ -709,22 +777,27 @@ export function RichTextEditor({
709
777
  const typeSpeed = 30; // ms per character
710
778
 
711
779
  const typeNextChar = () => {
712
- if (currentIndex < result.length) {
780
+ if (currentIndex < result.length && isTypingRef.current) {
713
781
  const nextChar = result[currentIndex];
714
782
  setTypingText(prev => prev + nextChar);
715
783
  editor.chain().focus().insertContent(nextChar).run();
716
784
  currentIndex++;
785
+ setRemainingText(result.substring(currentIndex));
717
786
  typingIntervalRef.current = setTimeout(typeNextChar, typeSpeed);
718
787
  } else {
719
- // Typing complete
788
+ // Typing complete or stopped
720
789
  setIsTyping(false);
790
+ isTypingRef.current = false;
721
791
  setTypingText('');
792
+ setRemainingText('');
722
793
 
723
- // Success toast
724
- toast({
725
- title: "AI action completed",
726
- description: "Your text has been updated successfully.",
727
- });
794
+ if (currentIndex >= result.length) {
795
+ // Success toast only if completed
796
+ toast({
797
+ title: "AI action completed",
798
+ description: "Your text has been updated successfully.",
799
+ });
800
+ }
728
801
  }
729
802
  };
730
803
 
@@ -1364,6 +1437,17 @@ export function RichTextEditor({
1364
1437
  {isTyping ? 'Typing...' : 'AI Tools'}
1365
1438
  </Button>
1366
1439
  </DropdownMenuTrigger>
1440
+ {isTyping && (
1441
+ <Button
1442
+ variant="destructive"
1443
+ size="sm"
1444
+ className="h-8 px-2"
1445
+ onClick={stopTyping}
1446
+ title="Stop AI typing"
1447
+ >
1448
+ <X className="w-4 h-4" />
1449
+ </Button>
1450
+ )}
1367
1451
  <DropdownMenuContent className="w-64">
1368
1452
  <div className="px-2 py-1.5 text-xs font-semibold text-muted-foreground flex items-center gap-2">
1369
1453
  <Wand2 className="w-3 h-3" />