@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.d.cts CHANGED
@@ -187,7 +187,7 @@ interface NotificationsWidgetProps {
187
187
  pulseStyle?: PulseStyle;
188
188
  soundCooldown?: number;
189
189
  }
190
- declare function NotificationsWidget({ notifications, onMarkAsRead, onMarkAllAsRead, onDismiss, onClearAll, onNotificationClick, size, maxVisible, playSound: _playSound, soundUrl, className, emptyMessage, title, dotColor, showPulse, soundType, pulseStyle, soundCooldown, }: NotificationsWidgetProps): react_jsx_runtime.JSX.Element;
190
+ declare function NotificationsWidget({ notifications, onMarkAsRead, onMarkAllAsRead, onDismiss, onClearAll, onNotificationClick, size, maxVisible, playSound, soundUrl, className, emptyMessage, title, dotColor, showPulse, soundType, pulseStyle, soundCooldown, }: NotificationsWidgetProps): react_jsx_runtime.JSX.Element;
191
191
 
192
192
  declare const buttonVariants: (props?: ({
193
193
  variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
package/dist/index.d.ts CHANGED
@@ -187,7 +187,7 @@ interface NotificationsWidgetProps {
187
187
  pulseStyle?: PulseStyle;
188
188
  soundCooldown?: number;
189
189
  }
190
- declare function NotificationsWidget({ notifications, onMarkAsRead, onMarkAllAsRead, onDismiss, onClearAll, onNotificationClick, size, maxVisible, playSound: _playSound, soundUrl, className, emptyMessage, title, dotColor, showPulse, soundType, pulseStyle, soundCooldown, }: NotificationsWidgetProps): react_jsx_runtime.JSX.Element;
190
+ declare function NotificationsWidget({ notifications, onMarkAsRead, onMarkAllAsRead, onDismiss, onClearAll, onNotificationClick, size, maxVisible, playSound, soundUrl, className, emptyMessage, title, dotColor, showPulse, soundType, pulseStyle, soundCooldown, }: NotificationsWidgetProps): react_jsx_runtime.JSX.Element;
191
191
 
192
192
  declare const buttonVariants: (props?: ({
193
193
  variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
package/dist/index.js CHANGED
@@ -9630,9 +9630,11 @@ function AvatarEditor({
9630
9630
  const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
9631
9631
  const [showGrid, setShowGrid] = useState(initialShowGrid);
9632
9632
  useEffect(() => {
9633
- if (imageSource && !imageSource.startsWith("data:")) {
9633
+ if (imageSource) {
9634
9634
  const img = new Image();
9635
- img.crossOrigin = "anonymous";
9635
+ if (!imageSource.startsWith("data:")) {
9636
+ img.crossOrigin = "anonymous";
9637
+ }
9636
9638
  img.onload = () => {
9637
9639
  setImage(img);
9638
9640
  setImageLoaded(true);
@@ -9641,6 +9643,12 @@ function AvatarEditor({
9641
9643
  setPosition({ x: 0, y: 0 });
9642
9644
  };
9643
9645
  img.src = imageSource;
9646
+ } else {
9647
+ setImage(null);
9648
+ setImageLoaded(false);
9649
+ setZoom(1);
9650
+ setRotation(0);
9651
+ setPosition({ x: 0, y: 0 });
9644
9652
  }
9645
9653
  }, [imageSource]);
9646
9654
  const generateOutput = useCallback(() => {
@@ -9820,6 +9828,7 @@ function AvatarEditor({
9820
9828
  const handleTouchMove = useCallback(
9821
9829
  (e) => {
9822
9830
  if (!isDragging) return;
9831
+ e.preventDefault();
9823
9832
  const touch = e.touches[0];
9824
9833
  setPosition({
9825
9834
  x: touch.clientX - dragStart.x,
@@ -10402,14 +10411,13 @@ function DrawerDescription({
10402
10411
  function useMediaQuery(query) {
10403
10412
  const [matches, setMatches] = useState(false);
10404
10413
  useEffect(() => {
10414
+ if (typeof window === "undefined") return;
10405
10415
  const media = window.matchMedia(query);
10406
- if (media.matches !== matches) {
10407
- setMatches(media.matches);
10408
- }
10416
+ setMatches(media.matches);
10409
10417
  const listener = () => setMatches(media.matches);
10410
10418
  media.addEventListener("change", listener);
10411
10419
  return () => media.removeEventListener("change", listener);
10412
- }, [matches, query]);
10420
+ }, [query]);
10413
10421
  return matches;
10414
10422
  }
10415
10423
  function AvatarEditorDialog({
@@ -10432,7 +10440,15 @@ function AvatarEditorDialog({
10432
10440
  const [editedValue, setEditedValue] = useState(value ?? null);
10433
10441
  const [isSaving, setIsSaving] = useState(false);
10434
10442
  const [feedback, setFeedback] = useState(null);
10443
+ const [mobileEditorSize, setMobileEditorSize] = useState(editorSize);
10435
10444
  const isMobile = useMediaQuery("(max-width: 640px)");
10445
+ useEffect(() => {
10446
+ if (typeof window !== "undefined" && isMobile) {
10447
+ setMobileEditorSize(Math.min(editorSize + 40, window.innerWidth - 48));
10448
+ } else {
10449
+ setMobileEditorSize(editorSize);
10450
+ }
10451
+ }, [isMobile, editorSize]);
10436
10452
  const handleOpenChange = useCallback(
10437
10453
  (open) => {
10438
10454
  if (open) {
@@ -10507,7 +10523,6 @@ function AvatarEditorDialog({
10507
10523
  ]
10508
10524
  }
10509
10525
  );
10510
- const mobileEditorSize = isMobile ? Math.min(editorSize + 40, window.innerWidth - 48) : editorSize;
10511
10526
  const EditorContent = /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4", children: [
10512
10527
  /* @__PURE__ */ jsx(
10513
10528
  AvatarEditor,
@@ -10832,7 +10847,7 @@ function NotificationsWidget({
10832
10847
  onNotificationClick,
10833
10848
  size: size4 = "md",
10834
10849
  maxVisible = 5,
10835
- playSound: _playSound = true,
10850
+ playSound = true,
10836
10851
  soundUrl,
10837
10852
  className,
10838
10853
  emptyMessage = "No notifications",
@@ -10849,10 +10864,13 @@ function NotificationsWidget({
10849
10864
  const styles = sizeConfig[size4];
10850
10865
  const dotBgColor = dotColorConfig[dotColor];
10851
10866
  const unreadCount = notifications.filter((n) => !n.read).length;
10852
- const visibleNotifications = notifications.slice(0, maxVisible);
10867
+ const visibleNotifications = React32.useMemo(
10868
+ () => notifications.slice(0, maxVisible),
10869
+ [notifications, maxVisible]
10870
+ );
10853
10871
  const hasMore = notifications.length > maxVisible;
10854
10872
  React32.useEffect(() => {
10855
- if (soundType !== "none" && unreadCount > prevCount && prevCount > 0) {
10873
+ if (playSound && soundType !== "none" && unreadCount > prevCount && prevCount > 0) {
10856
10874
  const now = Date.now();
10857
10875
  if (now - lastSoundPlayedRef.current >= soundCooldown) {
10858
10876
  playNotificationSound(soundType, soundUrl);
@@ -10860,7 +10878,7 @@ function NotificationsWidget({
10860
10878
  }
10861
10879
  }
10862
10880
  setPrevCount(unreadCount);
10863
- }, [unreadCount, prevCount, soundType, soundUrl, soundCooldown]);
10881
+ }, [unreadCount, prevCount, soundType, soundUrl, soundCooldown, playSound]);
10864
10882
  React32.useEffect(() => {
10865
10883
  if (isOpen && onMarkAsRead) {
10866
10884
  visibleNotifications.forEach((notification) => {
@@ -10954,18 +10972,32 @@ function NotificationsWidget({
10954
10972
  const config = typeConfig[notification.type || "info"];
10955
10973
  const Icon = config.icon;
10956
10974
  const hasLink = !!notification.href;
10975
+ const handleClick = () => handleNotificationClick(notification);
10976
+ const handleKeyDown = (e) => {
10977
+ if (e.key === "Enter" || e.key === " ") {
10978
+ e.preventDefault();
10979
+ handleNotificationClick(notification);
10980
+ }
10981
+ };
10982
+ const MotionElement = hasLink ? motion.button : motion.div;
10983
+ const interactionProps = hasLink ? {
10984
+ role: "button",
10985
+ tabIndex: 0,
10986
+ onClick: handleClick,
10987
+ onKeyDown: handleKeyDown
10988
+ } : {};
10957
10989
  return /* @__PURE__ */ jsxs(
10958
- motion.div,
10990
+ MotionElement,
10959
10991
  {
10960
10992
  initial: { opacity: 0, y: -10 },
10961
10993
  animate: { opacity: 1, y: 0 },
10962
10994
  className: cn(
10963
- "relative flex gap-3 px-4 py-3 transition-colors group",
10995
+ "relative flex gap-3 px-4 py-3 transition-colors group w-full text-left border-0 bg-transparent",
10964
10996
  hasLink && "cursor-pointer hover:bg-muted/50",
10965
10997
  !hasLink && "cursor-default",
10966
10998
  !notification.read && "bg-primary/5"
10967
10999
  ),
10968
- onClick: () => handleNotificationClick(notification),
11000
+ ...interactionProps,
10969
11001
  children: [
10970
11002
  /* @__PURE__ */ jsx(
10971
11003
  "div",