@mmmmzxe/react-360-viewer 0.1.2 → 0.1.4
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.ts +3 -2
- package/dist/index.js +125 -166
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/constants/viewer360ClassNames.ts +3 -2
- package/src/constants/viewer360Labels.ts +1 -1
- package/src/feature/Viewer360HotspotOverlay.tsx +16 -29
- package/src/feature/Viewer360MarkerPin.tsx +41 -40
- package/src/types/Viewer360Marker.ts +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React$1 from 'react';
|
|
2
|
-
import { ReactNode,
|
|
2
|
+
import { ReactNode, MouseEvent, CSSProperties, JSX, RefObject, PointerEvent, WheelEvent } from 'react';
|
|
3
3
|
import { ClassValue } from 'clsx';
|
|
4
4
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
5
5
|
import { VariantProps } from 'class-variance-authority';
|
|
@@ -104,6 +104,7 @@ type Viewer360MarkerPinProps<TData = unknown> = {
|
|
|
104
104
|
topPercent: number;
|
|
105
105
|
onDelete?: (id: string) => void;
|
|
106
106
|
isDeletePending?: boolean;
|
|
107
|
+
onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
|
|
107
108
|
renderTag?: (props: Viewer360MarkerPinRenderProps<TData>) => ReactNode;
|
|
108
109
|
classNames?: Viewer360MarkerPinClassNames;
|
|
109
110
|
labels?: Viewer360MarkerPinLabels;
|
|
@@ -230,7 +231,7 @@ type Viewer360LoadingOverlayProps = {
|
|
|
230
231
|
};
|
|
231
232
|
declare function Viewer360LoadingOverlay({ className, textClassName, label }: Viewer360LoadingOverlayProps): JSX.Element;
|
|
232
233
|
|
|
233
|
-
declare function Viewer360MarkerPin<TData = unknown>({ marker, hotspot, leftPercent, topPercent, onDelete, isDeletePending, renderTag, classNames, labels, }: Viewer360MarkerPinProps<TData>): JSX.Element;
|
|
234
|
+
declare function Viewer360MarkerPin<TData = unknown>({ marker, hotspot, leftPercent, topPercent, onDelete, isDeletePending, onClick, renderTag, classNames, labels, }: Viewer360MarkerPinProps<TData>): JSX.Element;
|
|
234
235
|
|
|
235
236
|
type Viewer360ToolbarProps = Viewer360ToolbarRenderProps;
|
|
236
237
|
declare function Viewer360Toolbar({ showDragHint, showHotspotModeControl, showZoomControls, showResetControl, labels, isHotspotMode, zoom, minZoom, maxZoom, isResetDisabled, onHotspotModeChange, onZoomIn, onZoomOut, onResetView, }: Viewer360ToolbarProps): JSX.Element;
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/feature/Viewer360.tsx
|
|
4
|
-
import { useEffect as useEffect2, useMemo as useMemo2, useState as
|
|
4
|
+
import { useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
|
|
5
5
|
|
|
6
6
|
// src/constants/viewer360Labels.ts
|
|
7
7
|
var defaultViewer360Labels = {
|
|
8
8
|
loading: "Loading images\u2026",
|
|
9
9
|
dragHint: "Drag to rotate \u2022 Scroll to zoom",
|
|
10
|
-
frameIndicator: ({ current, total, label }) => label ? `${label}
|
|
10
|
+
frameIndicator: ({ current, total, label }) => label ? `${label} \xB7 ${current} / ${total}` : `${current} / ${total}`,
|
|
11
11
|
zoom: (percent) => `${percent}%`,
|
|
12
12
|
hotspotModeActive: "Click on the image to place a hotspot",
|
|
13
13
|
addHotspot: "Add hotspot",
|
|
@@ -25,7 +25,7 @@ var viewer360ClassNames = {
|
|
|
25
25
|
overlay: "pointer-events-none absolute inset-0 overflow-hidden",
|
|
26
26
|
loading: "absolute inset-0 flex items-center justify-center bg-muted/80",
|
|
27
27
|
loadingText: "text-sm text-muted-foreground",
|
|
28
|
-
frameIndicator: "pointer-events-none absolute bottom-4 start-
|
|
28
|
+
frameIndicator: "pointer-events-none absolute bottom-4 start-4 z-20 rounded-full border bg-background px-4 py-1.5 text-xs font-medium shadow-sm",
|
|
29
29
|
hotspotModeBanner: "pointer-events-none absolute top-4 start-1/2 z-20 -translate-x-1/2 rounded-full border border-amber-200 bg-amber-50 px-4 py-1.5 text-xs font-medium text-amber-800 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-400",
|
|
30
30
|
toolbar: "flex flex-wrap items-center justify-between gap-2 border-t px-4 py-3",
|
|
31
31
|
dragHint: "hidden text-xs text-muted-foreground sm:block",
|
|
@@ -577,73 +577,20 @@ function toViewer360Hotspots(markers, mapData) {
|
|
|
577
577
|
}));
|
|
578
578
|
}
|
|
579
579
|
|
|
580
|
-
// src/components/ui/
|
|
580
|
+
// src/components/ui/Item/index.tsx
|
|
581
581
|
import { cva as cva2 } from "class-variance-authority";
|
|
582
582
|
import { Slot as Slot2 } from "radix-ui";
|
|
583
|
-
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
584
|
-
var buttonVariants = cva2(
|
|
585
|
-
"focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-md border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none",
|
|
586
|
-
{
|
|
587
|
-
variants: {
|
|
588
|
-
variant: {
|
|
589
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
590
|
-
outline: "border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground shadow-xs",
|
|
591
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
592
|
-
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
593
|
-
destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
|
|
594
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
595
|
-
},
|
|
596
|
-
size: {
|
|
597
|
-
default: "h-9 gap-1.5 px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2",
|
|
598
|
-
xs: "h-6 gap-1 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5",
|
|
599
|
-
sm: "h-8 gap-1 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5",
|
|
600
|
-
lg: "h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pe-3 has-data-[icon=inline-start]:ps-3",
|
|
601
|
-
icon: "size-9",
|
|
602
|
-
"icon-xs": "size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md",
|
|
603
|
-
"icon-sm": "size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md",
|
|
604
|
-
"icon-lg": "size-10"
|
|
605
|
-
}
|
|
606
|
-
},
|
|
607
|
-
defaultVariants: {
|
|
608
|
-
variant: "default",
|
|
609
|
-
size: "default"
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
);
|
|
613
|
-
function Button({
|
|
614
|
-
className,
|
|
615
|
-
variant = "default",
|
|
616
|
-
size = "default",
|
|
617
|
-
asChild = false,
|
|
618
|
-
...props
|
|
619
|
-
}) {
|
|
620
|
-
const Comp = asChild ? Slot2.Root : "button";
|
|
621
|
-
return /* @__PURE__ */ jsx5(
|
|
622
|
-
Comp,
|
|
623
|
-
{
|
|
624
|
-
"data-slot": "button",
|
|
625
|
-
"data-variant": variant,
|
|
626
|
-
"data-size": size,
|
|
627
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
628
|
-
...props
|
|
629
|
-
}
|
|
630
|
-
);
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
// src/components/ui/Item/index.tsx
|
|
634
|
-
import { cva as cva3 } from "class-variance-authority";
|
|
635
|
-
import { Slot as Slot3 } from "radix-ui";
|
|
636
583
|
|
|
637
584
|
// src/components/ui/Separator/index.tsx
|
|
638
585
|
import { Separator as SeparatorPrimitive } from "radix-ui";
|
|
639
|
-
import { jsx as
|
|
586
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
640
587
|
function Separator({
|
|
641
588
|
className,
|
|
642
589
|
orientation = "horizontal",
|
|
643
590
|
decorative = true,
|
|
644
591
|
...props
|
|
645
592
|
}) {
|
|
646
|
-
return /* @__PURE__ */
|
|
593
|
+
return /* @__PURE__ */ jsx5(
|
|
647
594
|
SeparatorPrimitive.Root,
|
|
648
595
|
{
|
|
649
596
|
"data-slot": "separator",
|
|
@@ -659,8 +606,8 @@ function Separator({
|
|
|
659
606
|
}
|
|
660
607
|
|
|
661
608
|
// src/components/ui/Item/index.tsx
|
|
662
|
-
import { jsx as
|
|
663
|
-
var itemVariants =
|
|
609
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
610
|
+
var itemVariants = cva2(
|
|
664
611
|
"[a]:hover:bg-muted rounded-md border text-sm w-full group/item focus-visible:border-ring focus-visible:ring-ring/50 flex items-center flex-wrap outline-none transition-colors duration-100 focus-visible:ring-[3px] [a]:transition-colors",
|
|
665
612
|
{
|
|
666
613
|
variants: {
|
|
@@ -688,8 +635,8 @@ function Item({
|
|
|
688
635
|
asChild = false,
|
|
689
636
|
...props
|
|
690
637
|
}) {
|
|
691
|
-
const Comp = asChild ?
|
|
692
|
-
return /* @__PURE__ */
|
|
638
|
+
const Comp = asChild ? Slot2.Root : "div";
|
|
639
|
+
return /* @__PURE__ */ jsx6(
|
|
693
640
|
Comp,
|
|
694
641
|
{
|
|
695
642
|
"data-slot": "item",
|
|
@@ -700,7 +647,7 @@ function Item({
|
|
|
700
647
|
}
|
|
701
648
|
);
|
|
702
649
|
}
|
|
703
|
-
var itemMediaVariants =
|
|
650
|
+
var itemMediaVariants = cva2(
|
|
704
651
|
"gap-2 group-has-[[data-slot=item-description]]/item:translate-y-0.5 group-has-[[data-slot=item-description]]/item:self-start flex shrink-0 items-center justify-center [&_svg]:pointer-events-none",
|
|
705
652
|
{
|
|
706
653
|
variants: {
|
|
@@ -716,7 +663,7 @@ var itemMediaVariants = cva3(
|
|
|
716
663
|
}
|
|
717
664
|
);
|
|
718
665
|
function ItemContent({ className, ...props }) {
|
|
719
|
-
return /* @__PURE__ */
|
|
666
|
+
return /* @__PURE__ */ jsx6(
|
|
720
667
|
"div",
|
|
721
668
|
{
|
|
722
669
|
"data-slot": "item-content",
|
|
@@ -726,7 +673,7 @@ function ItemContent({ className, ...props }) {
|
|
|
726
673
|
);
|
|
727
674
|
}
|
|
728
675
|
function ItemTitle({ className, ...props }) {
|
|
729
|
-
return /* @__PURE__ */
|
|
676
|
+
return /* @__PURE__ */ jsx6(
|
|
730
677
|
"div",
|
|
731
678
|
{
|
|
732
679
|
"data-slot": "item-title",
|
|
@@ -736,7 +683,7 @@ function ItemTitle({ className, ...props }) {
|
|
|
736
683
|
);
|
|
737
684
|
}
|
|
738
685
|
function ItemDescription({ className, ...props }) {
|
|
739
|
-
return /* @__PURE__ */
|
|
686
|
+
return /* @__PURE__ */ jsx6(
|
|
740
687
|
"p",
|
|
741
688
|
{
|
|
742
689
|
"data-slot": "item-description",
|
|
@@ -749,11 +696,10 @@ function ItemDescription({ className, ...props }) {
|
|
|
749
696
|
);
|
|
750
697
|
}
|
|
751
698
|
function ItemActions({ className, ...props }) {
|
|
752
|
-
return /* @__PURE__ */
|
|
699
|
+
return /* @__PURE__ */ jsx6("div", { "data-slot": "item-actions", className: cn("gap-2 flex items-center", className), ...props });
|
|
753
700
|
}
|
|
754
701
|
|
|
755
702
|
// src/feature/Viewer360MarkerPin.tsx
|
|
756
|
-
import { useState as useState2 } from "react";
|
|
757
703
|
import { Trash2 } from "lucide-react";
|
|
758
704
|
|
|
759
705
|
// src/constants/viewer360MarkerLabels.ts
|
|
@@ -761,38 +707,61 @@ var defaultViewer360MarkerPinLabels = {
|
|
|
761
707
|
delete: "Remove marker"
|
|
762
708
|
};
|
|
763
709
|
|
|
764
|
-
// src/components/ui/
|
|
765
|
-
import {
|
|
766
|
-
import {
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
710
|
+
// src/components/ui/Button/index.tsx
|
|
711
|
+
import { cva as cva3 } from "class-variance-authority";
|
|
712
|
+
import { Slot as Slot3 } from "radix-ui";
|
|
713
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
714
|
+
var buttonVariants = cva3(
|
|
715
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-md border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none",
|
|
716
|
+
{
|
|
717
|
+
variants: {
|
|
718
|
+
variant: {
|
|
719
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
720
|
+
outline: "border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground shadow-xs",
|
|
721
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
722
|
+
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
723
|
+
destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
|
|
724
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
725
|
+
},
|
|
726
|
+
size: {
|
|
727
|
+
default: "h-9 gap-1.5 px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pe-2 has-data-[icon=inline-start]:ps-2",
|
|
728
|
+
xs: "h-6 gap-1 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5",
|
|
729
|
+
sm: "h-8 gap-1 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5",
|
|
730
|
+
lg: "h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pe-3 has-data-[icon=inline-start]:ps-3",
|
|
731
|
+
icon: "size-9",
|
|
732
|
+
"icon-xs": "size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md",
|
|
733
|
+
"icon-sm": "size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md",
|
|
734
|
+
"icon-lg": "size-10"
|
|
735
|
+
}
|
|
736
|
+
},
|
|
737
|
+
defaultVariants: {
|
|
738
|
+
variant: "default",
|
|
739
|
+
size: "default"
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
);
|
|
743
|
+
function Button({
|
|
774
744
|
className,
|
|
775
|
-
|
|
776
|
-
|
|
745
|
+
variant = "default",
|
|
746
|
+
size = "default",
|
|
747
|
+
asChild = false,
|
|
777
748
|
...props
|
|
778
749
|
}) {
|
|
779
|
-
|
|
780
|
-
|
|
750
|
+
const Comp = asChild ? Slot3.Root : "button";
|
|
751
|
+
return /* @__PURE__ */ jsx7(
|
|
752
|
+
Comp,
|
|
781
753
|
{
|
|
782
|
-
"data-slot": "
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
className: cn(
|
|
786
|
-
"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=start]:slide-in-from-end-2 data-[side=end]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 flex flex-col gap-4 rounded-md p-4 text-sm shadow-md ring-1 duration-100 z-50 w-72 origin-(--radix-popover-content-transform-origin) outline-hidden",
|
|
787
|
-
className
|
|
788
|
-
),
|
|
754
|
+
"data-slot": "button",
|
|
755
|
+
"data-variant": variant,
|
|
756
|
+
"data-size": size,
|
|
757
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
789
758
|
...props
|
|
790
759
|
}
|
|
791
|
-
)
|
|
760
|
+
);
|
|
792
761
|
}
|
|
793
762
|
|
|
794
763
|
// src/feature/Viewer360MarkerPin.tsx
|
|
795
|
-
import { jsx as
|
|
764
|
+
import { jsx as jsx8, jsxs } from "react/jsx-runtime";
|
|
796
765
|
function Viewer360MarkerPin({
|
|
797
766
|
marker,
|
|
798
767
|
hotspot,
|
|
@@ -800,23 +769,26 @@ function Viewer360MarkerPin({
|
|
|
800
769
|
topPercent,
|
|
801
770
|
onDelete,
|
|
802
771
|
isDeletePending = false,
|
|
772
|
+
onClick,
|
|
803
773
|
renderTag,
|
|
804
774
|
classNames,
|
|
805
775
|
labels
|
|
806
776
|
}) {
|
|
807
|
-
const [isOpen, setIsOpen] = useState2(false);
|
|
808
777
|
const deleteLabel = labels?.delete ?? defaultViewer360MarkerPinLabels.delete;
|
|
809
|
-
|
|
778
|
+
const showTooltip = Boolean(marker.title || marker.description || onDelete || renderTag);
|
|
779
|
+
return /* @__PURE__ */ jsxs(
|
|
810
780
|
Item,
|
|
811
781
|
{
|
|
812
782
|
size: "xs",
|
|
813
783
|
variant: "default",
|
|
814
|
-
className: cn(
|
|
784
|
+
className: cn(
|
|
785
|
+
viewer360MarkerPinClassNames.root,
|
|
786
|
+
classNames?.root,
|
|
787
|
+
"group/marker w-auto border-transparent p-0"
|
|
788
|
+
),
|
|
815
789
|
style: { left: `${leftPercent}%`, top: `${topPercent}%` },
|
|
816
|
-
onMouseEnter: () => setIsOpen(true),
|
|
817
|
-
onMouseLeave: () => setIsOpen(false),
|
|
818
790
|
children: [
|
|
819
|
-
/* @__PURE__ */
|
|
791
|
+
/* @__PURE__ */ jsx8(
|
|
820
792
|
Badge,
|
|
821
793
|
{
|
|
822
794
|
variant: "destructive",
|
|
@@ -824,7 +796,7 @@ function Viewer360MarkerPin({
|
|
|
824
796
|
"aria-hidden": "true"
|
|
825
797
|
}
|
|
826
798
|
),
|
|
827
|
-
/* @__PURE__ */
|
|
799
|
+
/* @__PURE__ */ jsx8(
|
|
828
800
|
Button,
|
|
829
801
|
{
|
|
830
802
|
type: "button",
|
|
@@ -835,16 +807,18 @@ function Viewer360MarkerPin({
|
|
|
835
807
|
classNames?.dot,
|
|
836
808
|
"size-4 min-h-4 min-w-4 rounded-full border-2 border-background bg-destructive p-0 shadow-md hover:scale-125 hover:bg-destructive"
|
|
837
809
|
),
|
|
838
|
-
"aria-label": marker.title
|
|
810
|
+
"aria-label": marker.title,
|
|
811
|
+
onClick
|
|
839
812
|
}
|
|
840
|
-
)
|
|
841
|
-
/* @__PURE__ */
|
|
842
|
-
|
|
813
|
+
),
|
|
814
|
+
showTooltip && /* @__PURE__ */ jsx8(
|
|
815
|
+
"div",
|
|
843
816
|
{
|
|
844
|
-
className: cn(
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
817
|
+
className: cn(
|
|
818
|
+
viewer360MarkerPinClassNames.tooltip,
|
|
819
|
+
classNames?.tooltip,
|
|
820
|
+
"pointer-events-none opacity-0 transition-opacity duration-150 group-hover/marker:pointer-events-auto group-hover/marker:opacity-100 group-focus-within/marker:pointer-events-auto group-focus-within/marker:opacity-100"
|
|
821
|
+
),
|
|
848
822
|
children: /* @__PURE__ */ jsxs(
|
|
849
823
|
Item,
|
|
850
824
|
{
|
|
@@ -853,11 +827,11 @@ function Viewer360MarkerPin({
|
|
|
853
827
|
className: cn(viewer360MarkerPinClassNames.tooltipHeader, classNames?.tooltipHeader, "w-full border-transparent"),
|
|
854
828
|
children: [
|
|
855
829
|
/* @__PURE__ */ jsxs(ItemContent, { className: cn(viewer360MarkerPinClassNames.tooltipBody, classNames?.tooltipBody), children: [
|
|
856
|
-
/* @__PURE__ */
|
|
830
|
+
/* @__PURE__ */ jsx8(ItemTitle, { className: cn(viewer360MarkerPinClassNames.tooltipTitle, classNames?.tooltipTitle), children: marker.title }),
|
|
857
831
|
renderTag?.({ marker, hotspot }),
|
|
858
|
-
marker.description && /* @__PURE__ */
|
|
832
|
+
marker.description && /* @__PURE__ */ jsx8(ItemDescription, { className: cn(viewer360MarkerPinClassNames.tooltipDescription, classNames?.tooltipDescription), children: marker.description })
|
|
859
833
|
] }),
|
|
860
|
-
onDelete && /* @__PURE__ */
|
|
834
|
+
onDelete && /* @__PURE__ */ jsx8(ItemActions, { children: /* @__PURE__ */ jsx8(
|
|
861
835
|
Button,
|
|
862
836
|
{
|
|
863
837
|
variant: "ghost",
|
|
@@ -869,7 +843,7 @@ function Viewer360MarkerPin({
|
|
|
869
843
|
event.stopPropagation();
|
|
870
844
|
onDelete(marker.id);
|
|
871
845
|
},
|
|
872
|
-
children: /* @__PURE__ */
|
|
846
|
+
children: /* @__PURE__ */ jsx8(Trash2, { className: "size-4" })
|
|
873
847
|
}
|
|
874
848
|
) })
|
|
875
849
|
]
|
|
@@ -879,11 +853,11 @@ function Viewer360MarkerPin({
|
|
|
879
853
|
)
|
|
880
854
|
]
|
|
881
855
|
}
|
|
882
|
-
)
|
|
856
|
+
);
|
|
883
857
|
}
|
|
884
858
|
|
|
885
859
|
// src/feature/Viewer360HotspotOverlay.tsx
|
|
886
|
-
import { jsx as
|
|
860
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
887
861
|
function Viewer360HotspotOverlay({
|
|
888
862
|
hotspot,
|
|
889
863
|
leftPercent,
|
|
@@ -893,45 +867,30 @@ function Viewer360HotspotOverlay({
|
|
|
893
867
|
onHotspotClick
|
|
894
868
|
}) {
|
|
895
869
|
if (renderHotspot) {
|
|
896
|
-
return /* @__PURE__ */
|
|
897
|
-
}
|
|
898
|
-
if (hotspotPin) {
|
|
899
|
-
const marker = hotspotPin.getMarker?.(hotspot) ?? hotspotToViewer360Marker(hotspot);
|
|
900
|
-
return /* @__PURE__ */ jsx10(
|
|
901
|
-
Viewer360MarkerPin,
|
|
902
|
-
{
|
|
903
|
-
marker,
|
|
904
|
-
hotspot,
|
|
905
|
-
leftPercent,
|
|
906
|
-
topPercent,
|
|
907
|
-
onDelete: hotspotPin.onDelete,
|
|
908
|
-
isDeletePending: hotspotPin.deletingMarkerId === hotspot.id,
|
|
909
|
-
renderTag: hotspotPin.renderTag,
|
|
910
|
-
classNames: hotspotPin.classNames,
|
|
911
|
-
labels: hotspotPin.labels
|
|
912
|
-
}
|
|
913
|
-
);
|
|
870
|
+
return /* @__PURE__ */ jsx9(Item, { size: "xs", variant: "default", className: "pointer-events-auto w-auto border-transparent p-0", children: renderHotspot({ hotspot, leftPercent, topPercent }) });
|
|
914
871
|
}
|
|
915
|
-
|
|
916
|
-
|
|
872
|
+
const marker = hotspotPin?.getMarker?.(hotspot) ?? hotspotToViewer360Marker(hotspot);
|
|
873
|
+
return /* @__PURE__ */ jsx9(
|
|
874
|
+
Viewer360MarkerPin,
|
|
917
875
|
{
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
876
|
+
marker,
|
|
877
|
+
hotspot,
|
|
878
|
+
leftPercent,
|
|
879
|
+
topPercent,
|
|
880
|
+
onDelete: hotspotPin?.onDelete,
|
|
881
|
+
isDeletePending: hotspotPin?.deletingMarkerId === hotspot.id,
|
|
882
|
+
renderTag: hotspotPin?.renderTag,
|
|
883
|
+
classNames: hotspotPin?.classNames,
|
|
884
|
+
labels: hotspotPin?.labels,
|
|
885
|
+
onClick: onHotspotClick ? (event) => onHotspotClick(hotspot, event) : void 0
|
|
927
886
|
}
|
|
928
887
|
);
|
|
929
888
|
}
|
|
930
889
|
|
|
931
890
|
// src/components/ui/Label/index.tsx
|
|
932
|
-
import { jsx as
|
|
891
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
933
892
|
function Label({ className, ...props }) {
|
|
934
|
-
return /* @__PURE__ */
|
|
893
|
+
return /* @__PURE__ */ jsx10(
|
|
935
894
|
"label",
|
|
936
895
|
{
|
|
937
896
|
"data-slot": "label",
|
|
@@ -946,13 +905,13 @@ function Label({ className, ...props }) {
|
|
|
946
905
|
|
|
947
906
|
// src/components/ui/Spinner/index.tsx
|
|
948
907
|
import { Loader2Icon } from "lucide-react";
|
|
949
|
-
import { jsx as
|
|
908
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
950
909
|
function Spinner({ className, ...props }) {
|
|
951
|
-
return /* @__PURE__ */
|
|
910
|
+
return /* @__PURE__ */ jsx11(Loader2Icon, { role: "status", "aria-label": "Loading", className: cn("size-4 animate-spin", className), ...props });
|
|
952
911
|
}
|
|
953
912
|
|
|
954
913
|
// src/feature/Viewer360LoadingOverlay.tsx
|
|
955
|
-
import { jsx as
|
|
914
|
+
import { jsx as jsx12, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
956
915
|
function Viewer360LoadingOverlay({ className, textClassName, label }) {
|
|
957
916
|
return /* @__PURE__ */ jsxs2(
|
|
958
917
|
Item,
|
|
@@ -961,8 +920,8 @@ function Viewer360LoadingOverlay({ className, textClassName, label }) {
|
|
|
961
920
|
variant: "muted",
|
|
962
921
|
className: cn("pointer-events-none w-auto justify-center border-transparent bg-muted/80", className),
|
|
963
922
|
children: [
|
|
964
|
-
/* @__PURE__ */
|
|
965
|
-
/* @__PURE__ */
|
|
923
|
+
/* @__PURE__ */ jsx12(Spinner, { className: "size-5 text-muted-foreground" }),
|
|
924
|
+
/* @__PURE__ */ jsx12(Label, { className: cn("font-normal text-muted-foreground", textClassName), children: label })
|
|
966
925
|
]
|
|
967
926
|
}
|
|
968
927
|
);
|
|
@@ -970,7 +929,7 @@ function Viewer360LoadingOverlay({ className, textClassName, label }) {
|
|
|
970
929
|
|
|
971
930
|
// src/feature/Viewer360Toolbar.tsx
|
|
972
931
|
import { Crosshair, Minus, Plus, RotateCcw, ZoomIn } from "lucide-react";
|
|
973
|
-
import { Fragment, jsx as
|
|
932
|
+
import { Fragment, jsx as jsx13, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
974
933
|
function Viewer360Toolbar({
|
|
975
934
|
showDragHint,
|
|
976
935
|
showHotspotModeControl,
|
|
@@ -988,30 +947,30 @@ function Viewer360Toolbar({
|
|
|
988
947
|
onResetView
|
|
989
948
|
}) {
|
|
990
949
|
return /* @__PURE__ */ jsxs3(CardFooter, { className: cn(viewer360ClassNames.toolbar, "gap-2 border-t px-4 py-3 pt-3"), children: [
|
|
991
|
-
showDragHint && /* @__PURE__ */
|
|
950
|
+
showDragHint && /* @__PURE__ */ jsx13(Label, { className: cn(viewer360ClassNames.dragHint, "font-normal text-muted-foreground"), children: labels.dragHint }),
|
|
992
951
|
/* @__PURE__ */ jsxs3("div", { className: viewer360ClassNames.controls, children: [
|
|
993
952
|
showHotspotModeControl && /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
994
953
|
/* @__PURE__ */ jsxs3(Button, { variant: isHotspotMode ? "default" : "outline", size: "sm", onClick: () => onHotspotModeChange(!isHotspotMode), children: [
|
|
995
|
-
/* @__PURE__ */
|
|
954
|
+
/* @__PURE__ */ jsx13(Crosshair, { className: "me-1.5 size-4" }),
|
|
996
955
|
labels.addHotspot
|
|
997
956
|
] }),
|
|
998
|
-
/* @__PURE__ */
|
|
957
|
+
/* @__PURE__ */ jsx13(Separator, { orientation: "vertical", className: cn(viewer360ClassNames.divider, "h-6") })
|
|
999
958
|
] }),
|
|
1000
959
|
showZoomControls && /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
1001
|
-
/* @__PURE__ */
|
|
960
|
+
/* @__PURE__ */ jsx13(Button, { variant: "outline", size: "icon-sm", disabled: zoom <= minZoom, "aria-label": labels.zoomOut, onClick: onZoomOut, children: /* @__PURE__ */ jsx13(Minus, { className: "size-4" }) }),
|
|
1002
961
|
/* @__PURE__ */ jsxs3(Badge, { variant: "outline", className: cn(viewer360ClassNames.zoomDisplay, "h-8 gap-1 px-2 py-1"), children: [
|
|
1003
|
-
/* @__PURE__ */
|
|
962
|
+
/* @__PURE__ */ jsx13(ZoomIn, { className: "size-3 text-muted-foreground" }),
|
|
1004
963
|
labels.zoom(Math.round(zoom * 100))
|
|
1005
964
|
] }),
|
|
1006
|
-
/* @__PURE__ */
|
|
965
|
+
/* @__PURE__ */ jsx13(Button, { variant: "outline", size: "icon-sm", disabled: zoom >= maxZoom, "aria-label": labels.zoomIn, onClick: onZoomIn, children: /* @__PURE__ */ jsx13(Plus, { className: "size-4" }) })
|
|
1007
966
|
] }),
|
|
1008
|
-
showResetControl && /* @__PURE__ */
|
|
967
|
+
showResetControl && /* @__PURE__ */ jsx13(Button, { variant: "outline", size: "icon-sm", disabled: isResetDisabled2, "aria-label": labels.resetView, onClick: onResetView, children: /* @__PURE__ */ jsx13(RotateCcw, { className: "size-4" }) })
|
|
1009
968
|
] })
|
|
1010
969
|
] });
|
|
1011
970
|
}
|
|
1012
971
|
|
|
1013
972
|
// src/feature/Viewer360.tsx
|
|
1014
|
-
import { jsx as
|
|
973
|
+
import { jsx as jsx14, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1015
974
|
function Viewer360({
|
|
1016
975
|
frames,
|
|
1017
976
|
currentFrameIndex: controlledFrameIndex,
|
|
@@ -1046,8 +1005,8 @@ function Viewer360({
|
|
|
1046
1005
|
const mergedLabels = useMemo2(() => mergeViewer360Labels(labels), [labels]);
|
|
1047
1006
|
const mergedClassNames = useMemo2(() => mergeViewer360ClassNames(classNames), [classNames]);
|
|
1048
1007
|
const themeStyle = useMemo2(() => buildViewer360ThemeStyle(theme), [theme]);
|
|
1049
|
-
const [internalFrameIndex, setInternalFrameIndex] =
|
|
1050
|
-
const [internalHotspotMode, setInternalHotspotMode] =
|
|
1008
|
+
const [internalFrameIndex, setInternalFrameIndex] = useState2(defaultFrameIndex);
|
|
1009
|
+
const [internalHotspotMode, setInternalHotspotMode] = useState2(defaultHotspotMode);
|
|
1051
1010
|
const currentFrameIndex = controlledFrameIndex ?? internalFrameIndex;
|
|
1052
1011
|
const hotspotMode = controlledHotspotMode ?? internalHotspotMode;
|
|
1053
1012
|
function handleFrameChange(index) {
|
|
@@ -1137,11 +1096,11 @@ function Viewer360({
|
|
|
1137
1096
|
onWheel: handleWheel,
|
|
1138
1097
|
onClick: handleCanvasClick,
|
|
1139
1098
|
children: [
|
|
1140
|
-
/* @__PURE__ */
|
|
1099
|
+
/* @__PURE__ */ jsx14("canvas", { ref: canvasRef, className: mergedClassNames.canvas }),
|
|
1141
1100
|
/* @__PURE__ */ jsxs4("div", { className: mergedClassNames.overlay, children: [
|
|
1142
1101
|
currentFrameHotspots.map((hotspot) => {
|
|
1143
1102
|
const position = getHotspotScreenPosition(hotspot);
|
|
1144
|
-
return /* @__PURE__ */
|
|
1103
|
+
return /* @__PURE__ */ jsx14(
|
|
1145
1104
|
Viewer360HotspotOverlay,
|
|
1146
1105
|
{
|
|
1147
1106
|
hotspot,
|
|
@@ -1156,7 +1115,7 @@ function Viewer360({
|
|
|
1156
1115
|
}),
|
|
1157
1116
|
children
|
|
1158
1117
|
] }),
|
|
1159
|
-
!imagesLoaded && (renderLoading ? renderLoading() : /* @__PURE__ */
|
|
1118
|
+
!imagesLoaded && (renderLoading ? renderLoading() : /* @__PURE__ */ jsx14(
|
|
1160
1119
|
Viewer360LoadingOverlay,
|
|
1161
1120
|
{
|
|
1162
1121
|
className: mergedClassNames.loading,
|
|
@@ -1164,7 +1123,7 @@ function Viewer360({
|
|
|
1164
1123
|
label: mergedLabels.loading
|
|
1165
1124
|
}
|
|
1166
1125
|
)),
|
|
1167
|
-
showFrameIndicator && frames.length > 0 && (renderFrameIndicator ? renderFrameIndicator(overlayProps) : /* @__PURE__ */
|
|
1126
|
+
showFrameIndicator && frames.length > 0 && (renderFrameIndicator ? renderFrameIndicator(overlayProps) : /* @__PURE__ */ jsx14(
|
|
1168
1127
|
Viewer360FrameIndicator,
|
|
1169
1128
|
{
|
|
1170
1129
|
className: mergedClassNames.frameIndicator,
|
|
@@ -1175,11 +1134,11 @@ function Viewer360({
|
|
|
1175
1134
|
})
|
|
1176
1135
|
}
|
|
1177
1136
|
)),
|
|
1178
|
-
isHotspotMode && onHotspotAdd && (renderHotspotModeBanner ? renderHotspotModeBanner({ labels: mergedLabels }) : /* @__PURE__ */
|
|
1137
|
+
isHotspotMode && onHotspotAdd && (renderHotspotModeBanner ? renderHotspotModeBanner({ labels: mergedLabels }) : /* @__PURE__ */ jsx14(Viewer360AddModeBanner, { className: mergedClassNames.hotspotModeBanner, label: mergedLabels.hotspotModeActive }))
|
|
1179
1138
|
]
|
|
1180
1139
|
}
|
|
1181
1140
|
),
|
|
1182
|
-
renderToolbar ? renderToolbar(toolbarProps) : showDefaultToolbar ? /* @__PURE__ */
|
|
1141
|
+
renderToolbar ? renderToolbar(toolbarProps) : showDefaultToolbar ? /* @__PURE__ */ jsx14(Viewer360Toolbar, { ...toolbarProps }) : null
|
|
1183
1142
|
] });
|
|
1184
1143
|
}
|
|
1185
1144
|
|