@janovix/blocks 1.0.0-rc.4 → 1.0.0-rc.6

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
@@ -9656,9 +9656,11 @@ function AvatarEditor({
9656
9656
  const [dragStart, setDragStart] = React32.useState({ x: 0, y: 0 });
9657
9657
  const [showGrid, setShowGrid] = React32.useState(initialShowGrid);
9658
9658
  React32.useEffect(() => {
9659
- if (imageSource && !imageSource.startsWith("data:")) {
9659
+ if (imageSource) {
9660
9660
  const img = new Image();
9661
- img.crossOrigin = "anonymous";
9661
+ if (!imageSource.startsWith("data:")) {
9662
+ img.crossOrigin = "anonymous";
9663
+ }
9662
9664
  img.onload = () => {
9663
9665
  setImage(img);
9664
9666
  setImageLoaded(true);
@@ -9667,6 +9669,12 @@ function AvatarEditor({
9667
9669
  setPosition({ x: 0, y: 0 });
9668
9670
  };
9669
9671
  img.src = imageSource;
9672
+ } else {
9673
+ setImage(null);
9674
+ setImageLoaded(false);
9675
+ setZoom(1);
9676
+ setRotation(0);
9677
+ setPosition({ x: 0, y: 0 });
9670
9678
  }
9671
9679
  }, [imageSource]);
9672
9680
  const generateOutput = React32.useCallback(() => {
@@ -9846,6 +9854,7 @@ function AvatarEditor({
9846
9854
  const handleTouchMove = React32.useCallback(
9847
9855
  (e) => {
9848
9856
  if (!isDragging) return;
9857
+ e.preventDefault();
9849
9858
  const touch = e.touches[0];
9850
9859
  setPosition({
9851
9860
  x: touch.clientX - dragStart.x,
@@ -10428,14 +10437,13 @@ function DrawerDescription({
10428
10437
  function useMediaQuery(query) {
10429
10438
  const [matches, setMatches] = React32.useState(false);
10430
10439
  React32.useEffect(() => {
10440
+ if (typeof window === "undefined") return;
10431
10441
  const media = window.matchMedia(query);
10432
- if (media.matches !== matches) {
10433
- setMatches(media.matches);
10434
- }
10442
+ setMatches(media.matches);
10435
10443
  const listener = () => setMatches(media.matches);
10436
10444
  media.addEventListener("change", listener);
10437
10445
  return () => media.removeEventListener("change", listener);
10438
- }, [matches, query]);
10446
+ }, [query]);
10439
10447
  return matches;
10440
10448
  }
10441
10449
  function AvatarEditorDialog({
@@ -10458,7 +10466,15 @@ function AvatarEditorDialog({
10458
10466
  const [editedValue, setEditedValue] = React32.useState(value ?? null);
10459
10467
  const [isSaving, setIsSaving] = React32.useState(false);
10460
10468
  const [feedback, setFeedback] = React32.useState(null);
10469
+ const [mobileEditorSize, setMobileEditorSize] = React32.useState(editorSize);
10461
10470
  const isMobile = useMediaQuery("(max-width: 640px)");
10471
+ React32.useEffect(() => {
10472
+ if (typeof window !== "undefined" && isMobile) {
10473
+ setMobileEditorSize(Math.min(editorSize + 40, window.innerWidth - 48));
10474
+ } else {
10475
+ setMobileEditorSize(editorSize);
10476
+ }
10477
+ }, [isMobile, editorSize]);
10462
10478
  const handleOpenChange = React32.useCallback(
10463
10479
  (open) => {
10464
10480
  if (open) {
@@ -10533,7 +10549,6 @@ function AvatarEditorDialog({
10533
10549
  ]
10534
10550
  }
10535
10551
  );
10536
- const mobileEditorSize = isMobile ? Math.min(editorSize + 40, window.innerWidth - 48) : editorSize;
10537
10552
  const EditorContent = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-4", children: [
10538
10553
  /* @__PURE__ */ jsxRuntime.jsx(
10539
10554
  AvatarEditor,
@@ -10858,7 +10873,7 @@ function NotificationsWidget({
10858
10873
  onNotificationClick,
10859
10874
  size: size4 = "md",
10860
10875
  maxVisible = 5,
10861
- playSound: _playSound = true,
10876
+ playSound = true,
10862
10877
  soundUrl,
10863
10878
  className,
10864
10879
  emptyMessage = "No notifications",
@@ -10875,10 +10890,13 @@ function NotificationsWidget({
10875
10890
  const styles = sizeConfig[size4];
10876
10891
  const dotBgColor = dotColorConfig[dotColor];
10877
10892
  const unreadCount = notifications.filter((n) => !n.read).length;
10878
- const visibleNotifications = notifications.slice(0, maxVisible);
10893
+ const visibleNotifications = React32__namespace.useMemo(
10894
+ () => notifications.slice(0, maxVisible),
10895
+ [notifications, maxVisible]
10896
+ );
10879
10897
  const hasMore = notifications.length > maxVisible;
10880
10898
  React32__namespace.useEffect(() => {
10881
- if (soundType !== "none" && unreadCount > prevCount && prevCount > 0) {
10899
+ if (playSound && soundType !== "none" && unreadCount > prevCount && prevCount > 0) {
10882
10900
  const now = Date.now();
10883
10901
  if (now - lastSoundPlayedRef.current >= soundCooldown) {
10884
10902
  playNotificationSound(soundType, soundUrl);
@@ -10886,7 +10904,7 @@ function NotificationsWidget({
10886
10904
  }
10887
10905
  }
10888
10906
  setPrevCount(unreadCount);
10889
- }, [unreadCount, prevCount, soundType, soundUrl, soundCooldown]);
10907
+ }, [unreadCount, prevCount, soundType, soundUrl, soundCooldown, playSound]);
10890
10908
  React32__namespace.useEffect(() => {
10891
10909
  if (isOpen && onMarkAsRead) {
10892
10910
  visibleNotifications.forEach((notification) => {
@@ -10980,18 +10998,32 @@ function NotificationsWidget({
10980
10998
  const config = typeConfig[notification.type || "info"];
10981
10999
  const Icon = config.icon;
10982
11000
  const hasLink = !!notification.href;
11001
+ const handleClick = () => handleNotificationClick(notification);
11002
+ const handleKeyDown = (e) => {
11003
+ if (e.key === "Enter" || e.key === " ") {
11004
+ e.preventDefault();
11005
+ handleNotificationClick(notification);
11006
+ }
11007
+ };
11008
+ const MotionElement = hasLink ? react.motion.button : react.motion.div;
11009
+ const interactionProps = hasLink ? {
11010
+ role: "button",
11011
+ tabIndex: 0,
11012
+ onClick: handleClick,
11013
+ onKeyDown: handleKeyDown
11014
+ } : {};
10983
11015
  return /* @__PURE__ */ jsxRuntime.jsxs(
10984
- react.motion.div,
11016
+ MotionElement,
10985
11017
  {
10986
11018
  initial: { opacity: 0, y: -10 },
10987
11019
  animate: { opacity: 1, y: 0 },
10988
11020
  className: cn(
10989
- "relative flex gap-3 px-4 py-3 transition-colors group",
11021
+ "relative flex gap-3 px-4 py-3 transition-colors group w-full text-left border-0 bg-transparent",
10990
11022
  hasLink && "cursor-pointer hover:bg-muted/50",
10991
11023
  !hasLink && "cursor-default",
10992
11024
  !notification.read && "bg-primary/5"
10993
11025
  ),
10994
- onClick: () => handleNotificationClick(notification),
11026
+ ...interactionProps,
10995
11027
  children: [
10996
11028
  /* @__PURE__ */ jsxRuntime.jsx(
10997
11029
  "div",