@janovix/blocks 1.2.0-rc.22 → 1.2.0-rc.23

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.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
  var React2 = require('react');
4
4
  var nextThemes = require('next-themes');
5
5
  var lucideReact = require('lucide-react');
6
- var react = require('motion/react');
6
+ var framerMotion = require('framer-motion');
7
7
  var DropdownMenuPrimitive = require('@radix-ui/react-dropdown-menu');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
  var reactSlot = require('@radix-ui/react-slot');
@@ -3551,8 +3551,8 @@ function ThemeSwitcher({
3551
3551
  onClick: () => handleThemeClick(key),
3552
3552
  type: "button",
3553
3553
  children: [
3554
- /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: isActive && /* @__PURE__ */ jsxRuntime.jsx(
3555
- react.motion.div,
3554
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isActive && /* @__PURE__ */ jsxRuntime.jsx(
3555
+ framerMotion.motion.div,
3556
3556
  {
3557
3557
  className: cn("absolute inset-0 bg-secondary", shapeClass),
3558
3558
  layoutId: "activeTheme",
@@ -3702,8 +3702,8 @@ function LanguageSwitcher({
3702
3702
  onClick: () => onLanguageChange?.(key),
3703
3703
  type: "button",
3704
3704
  children: [
3705
- /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: isActive && /* @__PURE__ */ jsxRuntime.jsx(
3706
- react.motion.div,
3705
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isActive && /* @__PURE__ */ jsxRuntime.jsx(
3706
+ framerMotion.motion.div,
3707
3707
  {
3708
3708
  className: cn("absolute inset-0 bg-secondary", shapeClass),
3709
3709
  layoutId: "activeLanguage",
@@ -3824,7 +3824,7 @@ function Toggle({
3824
3824
  );
3825
3825
  }
3826
3826
  function AvatarEditor({
3827
- value,
3827
+ value: _value,
3828
3828
  onChange,
3829
3829
  size = 280,
3830
3830
  showGrid: initialShowGrid = false,
@@ -3832,14 +3832,11 @@ function AvatarEditor({
3832
3832
  outputFormat = "png",
3833
3833
  outputQuality = 0.92,
3834
3834
  className,
3835
- controlSize = "default",
3836
- defaultImage,
3837
- initials: _initials
3835
+ controlSize = "default"
3838
3836
  }) {
3839
3837
  const canvasRef = React2.useRef(null);
3840
3838
  const fileInputRef = React2.useRef(null);
3841
3839
  const containerRef = React2.useRef(null);
3842
- const imageSource = value ?? defaultImage;
3843
3840
  const [image, setImage] = React2.useState(null);
3844
3841
  const [imageLoaded, setImageLoaded] = React2.useState(false);
3845
3842
  const [zoom, setZoom] = React2.useState(1);
@@ -3848,83 +3845,17 @@ function AvatarEditor({
3848
3845
  const [isDragging, setIsDragging] = React2.useState(false);
3849
3846
  const [dragStart, setDragStart] = React2.useState({ x: 0, y: 0 });
3850
3847
  const [showGrid, setShowGrid] = React2.useState(initialShowGrid);
3851
- React2.useEffect(() => {
3852
- if (imageSource) {
3853
- const img = new Image();
3854
- if (!imageSource.startsWith("data:")) {
3855
- img.crossOrigin = "anonymous";
3856
- }
3857
- img.onload = () => {
3858
- setImage(img);
3859
- setImageLoaded(true);
3860
- setZoom(1);
3861
- setRotation(0);
3862
- setPosition({ x: 0, y: 0 });
3863
- };
3864
- img.src = imageSource;
3865
- } else {
3866
- setImage(null);
3867
- setImageLoaded(false);
3868
- setZoom(1);
3869
- setRotation(0);
3870
- setPosition({ x: 0, y: 0 });
3871
- }
3872
- }, [imageSource]);
3873
3848
  const generateOutput = React2.useCallback(() => {
3874
- if (!image) return null;
3849
+ if (!canvasRef.current || !image) return null;
3875
3850
  const outputCanvas = document.createElement("canvas");
3876
3851
  outputCanvas.width = outputSize;
3877
3852
  outputCanvas.height = outputSize;
3878
3853
  const ctx = outputCanvas.getContext("2d");
3879
3854
  if (!ctx) return null;
3880
- ctx.imageSmoothingEnabled = true;
3881
- ctx.imageSmoothingQuality = "high";
3882
- if (outputFormat === "jpeg") {
3883
- ctx.fillStyle = "#ffffff";
3884
- ctx.fillRect(0, 0, outputSize, outputSize);
3885
- }
3886
- ctx.imageSmoothingEnabled = true;
3887
- ctx.imageSmoothingQuality = "high";
3888
- ctx.save();
3889
- ctx.translate(outputSize / 2, outputSize / 2);
3890
- ctx.rotate(rotation * Math.PI / 180);
3891
- const scale = zoom;
3892
- const imgAspect = image.width / image.height;
3893
- let drawWidth, drawHeight;
3894
- if (imgAspect > 1) {
3895
- drawHeight = outputSize * scale;
3896
- drawWidth = drawHeight * imgAspect;
3897
- } else {
3898
- drawWidth = outputSize * scale;
3899
- drawHeight = drawWidth / imgAspect;
3900
- }
3901
- const positionScale = outputSize / size;
3902
- const scaledPosX = position.x * positionScale;
3903
- const scaledPosY = position.y * positionScale;
3904
- ctx.drawImage(
3905
- image,
3906
- -drawWidth / 2 + scaledPosX,
3907
- -drawHeight / 2 + scaledPosY,
3908
- drawWidth,
3909
- drawHeight
3910
- );
3911
- ctx.restore();
3912
- ctx.globalCompositeOperation = "destination-in";
3913
- ctx.beginPath();
3914
- ctx.arc(outputSize / 2, outputSize / 2, outputSize / 2, 0, Math.PI * 2);
3915
- ctx.fill();
3855
+ ctx.drawImage(canvasRef.current, 0, 0, outputSize, outputSize);
3916
3856
  const mimeType = `image/${outputFormat}`;
3917
3857
  return outputCanvas.toDataURL(mimeType, outputQuality);
3918
- }, [
3919
- image,
3920
- outputSize,
3921
- outputFormat,
3922
- outputQuality,
3923
- zoom,
3924
- rotation,
3925
- position,
3926
- size
3927
- ]);
3858
+ }, [image, outputSize, outputFormat, outputQuality]);
3928
3859
  React2.useEffect(() => {
3929
3860
  if (!canvasRef.current || !image || !imageLoaded) return;
3930
3861
  const canvas = canvasRef.current;
@@ -3934,8 +3865,8 @@ function AvatarEditor({
3934
3865
  canvas.width = displaySize;
3935
3866
  canvas.height = displaySize;
3936
3867
  ctx.clearRect(0, 0, displaySize, displaySize);
3937
- ctx.imageSmoothingEnabled = true;
3938
- ctx.imageSmoothingQuality = "high";
3868
+ ctx.fillStyle = "#1a1a2e";
3869
+ ctx.fillRect(0, 0, displaySize, displaySize);
3939
3870
  ctx.save();
3940
3871
  ctx.translate(displaySize / 2, displaySize / 2);
3941
3872
  ctx.rotate(rotation * Math.PI / 180);
@@ -4053,7 +3984,6 @@ function AvatarEditor({
4053
3984
  const handleTouchMove = React2.useCallback(
4054
3985
  (e) => {
4055
3986
  if (!isDragging) return;
4056
- e.preventDefault();
4057
3987
  const touch = e.touches[0];
4058
3988
  setPosition({
4059
3989
  x: touch.clientX - dragStart.x,
@@ -4636,13 +4566,14 @@ function DrawerDescription({
4636
4566
  function useMediaQuery(query) {
4637
4567
  const [matches, setMatches] = React2.useState(false);
4638
4568
  React2.useEffect(() => {
4639
- if (typeof window === "undefined") return;
4640
4569
  const media = window.matchMedia(query);
4641
- setMatches(media.matches);
4570
+ if (media.matches !== matches) {
4571
+ setMatches(media.matches);
4572
+ }
4642
4573
  const listener = () => setMatches(media.matches);
4643
4574
  media.addEventListener("change", listener);
4644
4575
  return () => media.removeEventListener("change", listener);
4645
- }, [query]);
4576
+ }, [matches, query]);
4646
4577
  return matches;
4647
4578
  }
4648
4579
  function AvatarEditorDialog({
@@ -4652,7 +4583,7 @@ function AvatarEditorDialog({
4652
4583
  displaySize = 120,
4653
4584
  editorSize = 280,
4654
4585
  outputSize = 256,
4655
- placeholder: _placeholder = "Add Photo",
4586
+ placeholder = "Add Photo",
4656
4587
  editLabel = "Edit avatar",
4657
4588
  dialogTitle = "Edit Avatar",
4658
4589
  acceptText = "Accept",
@@ -4665,15 +4596,7 @@ function AvatarEditorDialog({
4665
4596
  const [editedValue, setEditedValue] = React2.useState(value ?? null);
4666
4597
  const [isSaving, setIsSaving] = React2.useState(false);
4667
4598
  const [feedback, setFeedback] = React2.useState(null);
4668
- const [mobileEditorSize, setMobileEditorSize] = React2.useState(editorSize);
4669
4599
  const isMobile = useMediaQuery("(max-width: 640px)");
4670
- React2.useEffect(() => {
4671
- if (typeof window !== "undefined" && isMobile) {
4672
- setMobileEditorSize(Math.min(editorSize + 40, window.innerWidth - 48));
4673
- } else {
4674
- setMobileEditorSize(editorSize);
4675
- }
4676
- }, [isMobile, editorSize]);
4677
4600
  const handleOpenChange = React2.useCallback(
4678
4601
  (open) => {
4679
4602
  if (open) {
@@ -4692,6 +4615,7 @@ function AvatarEditorDialog({
4692
4615
  if (onSave) {
4693
4616
  const result = await onSave(editedValue);
4694
4617
  if (result) {
4618
+ onChange?.(editedValue);
4695
4619
  setFeedback({ type: "success", message: successMessage });
4696
4620
  setTimeout(() => {
4697
4621
  setIsOpen(false);
@@ -4732,7 +4656,10 @@ function AvatarEditorDialog({
4732
4656
  alt: "Avatar",
4733
4657
  className: "w-full h-full object-cover"
4734
4658
  }
4735
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "w-10 h-10" }) })
4659
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center text-muted-foreground gap-1", children: [
4660
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "w-1/3 h-1/3" }),
4661
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", children: placeholder })
4662
+ ] })
4736
4663
  }
4737
4664
  ),
4738
4665
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -4748,6 +4675,7 @@ function AvatarEditorDialog({
4748
4675
  ]
4749
4676
  }
4750
4677
  );
4678
+ const mobileEditorSize = isMobile ? Math.min(editorSize + 40, window.innerWidth - 48) : editorSize;
4751
4679
  const EditorContent = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-4", children: [
4752
4680
  /* @__PURE__ */ jsxRuntime.jsx(
4753
4681
  AvatarEditor,
@@ -4759,8 +4687,8 @@ function AvatarEditorDialog({
4759
4687
  controlSize: isMobile ? "large" : "default"
4760
4688
  }
4761
4689
  ),
4762
- /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: feedback && /* @__PURE__ */ jsxRuntime.jsxs(
4763
- react.motion.div,
4690
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: feedback && /* @__PURE__ */ jsxRuntime.jsxs(
4691
+ framerMotion.motion.div,
4764
4692
  {
4765
4693
  initial: { opacity: 0, y: -10 },
4766
4694
  animate: { opacity: 1, y: 0 },
@@ -5203,7 +5131,7 @@ function NotificationsWidget({
5203
5131
  };
5204
5132
  return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
5205
5133
  /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
5206
- react.motion.button,
5134
+ framerMotion.motion.button,
5207
5135
  {
5208
5136
  className: cn(
5209
5137
  "relative inline-flex items-center justify-center rounded-lg",
@@ -5215,8 +5143,8 @@ function NotificationsWidget({
5215
5143
  "aria-label": `Notifications${unreadCount > 0 ? ` (${unreadCount} unread)` : ""}`,
5216
5144
  children: [
5217
5145
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bell, { className: cn(styles.icon, "text-muted-foreground") }),
5218
- /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
5219
- react.motion.div,
5146
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: unreadCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(
5147
+ framerMotion.motion.div,
5220
5148
  {
5221
5149
  initial: { scale: 0, opacity: 0 },
5222
5150
  animate: { scale: 1, opacity: 1 },
@@ -5228,8 +5156,8 @@ function NotificationsWidget({
5228
5156
  )
5229
5157
  }
5230
5158
  ) }),
5231
- /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: unreadCount > 0 && showPulse && pulseStyle !== "none" && /* @__PURE__ */ jsxRuntime.jsx(
5232
- react.motion.div,
5159
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: unreadCount > 0 && showPulse && pulseStyle !== "none" && /* @__PURE__ */ jsxRuntime.jsx(
5160
+ framerMotion.motion.div,
5233
5161
  {
5234
5162
  initial: { scale: 1, opacity: 0.5 },
5235
5163
  animate: pulseVariants[pulseStyle].animate,
@@ -5295,7 +5223,7 @@ function NotificationsWidget({
5295
5223
  handleNotificationClick(notification);
5296
5224
  }
5297
5225
  };
5298
- const MotionElement = hasLink ? react.motion.button : react.motion.div;
5226
+ const MotionElement = hasLink ? framerMotion.motion.button : framerMotion.motion.div;
5299
5227
  const interactionProps = hasLink ? {
5300
5228
  role: "button",
5301
5229
  tabIndex: 0,