@loafmarkets/ui 0.1.401 → 0.1.403
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.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +109 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +109 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1269,11 +1269,13 @@ type PropertyPhotoGalleryProps = {
|
|
|
1269
1269
|
isOpen: boolean;
|
|
1270
1270
|
onClose: () => void;
|
|
1271
1271
|
startIndex?: number;
|
|
1272
|
+
startWithVideo?: boolean;
|
|
1272
1273
|
images?: PropertyGalleryImage[];
|
|
1273
1274
|
title?: string;
|
|
1274
1275
|
subtitle?: string;
|
|
1276
|
+
videoUrl?: string;
|
|
1275
1277
|
};
|
|
1276
|
-
declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, title, subtitle, images, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
|
|
1278
|
+
declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, startWithVideo, title, subtitle, images, videoUrl, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
|
|
1277
1279
|
|
|
1278
1280
|
type UseAdaptivePollingOptions = {
|
|
1279
1281
|
enabled: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -1269,11 +1269,13 @@ type PropertyPhotoGalleryProps = {
|
|
|
1269
1269
|
isOpen: boolean;
|
|
1270
1270
|
onClose: () => void;
|
|
1271
1271
|
startIndex?: number;
|
|
1272
|
+
startWithVideo?: boolean;
|
|
1272
1273
|
images?: PropertyGalleryImage[];
|
|
1273
1274
|
title?: string;
|
|
1274
1275
|
subtitle?: string;
|
|
1276
|
+
videoUrl?: string;
|
|
1275
1277
|
};
|
|
1276
|
-
declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, title, subtitle, images, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
|
|
1278
|
+
declare function PropertyPhotoGallery({ isOpen, onClose, startIndex, startWithVideo, title, subtitle, images, videoUrl, }: PropertyPhotoGalleryProps): react_jsx_runtime.JSX.Element | null;
|
|
1277
1279
|
|
|
1278
1280
|
type UseAdaptivePollingOptions = {
|
|
1279
1281
|
enabled: boolean;
|
package/dist/index.js
CHANGED
|
@@ -10394,7 +10394,9 @@ function PropertyOverview({
|
|
|
10394
10394
|
];
|
|
10395
10395
|
const growthPct = overviewData?.growth5Yr;
|
|
10396
10396
|
const propertyStats = [
|
|
10397
|
-
|
|
10397
|
+
// Property Value = the API offeringValuation (OverviewResponse.offeringValuation), NOT
|
|
10398
|
+
// midPrice×tokensIssued market cap (fixed 2026-07-22). null → '—', never a fabricated cap.
|
|
10399
|
+
{ label: "Property Value", value: isLoading && overviewData?.offeringValuation == null ? loadingSkeleton : overviewData?.offeringValuation ? fmtDollar(overviewData.offeringValuation) : "\u2014" },
|
|
10398
10400
|
...beta ? [] : [{ label: "Offers", value: "3" }],
|
|
10399
10401
|
{ label: "Growth (5yr)", value: growthPct != null ? `${growthPct > 0 ? "+" : ""}${growthPct}%` : "\u2014" },
|
|
10400
10402
|
{ label: "Last Dividend", value: overviewData?.lastDividend != null ? `$${overviewData.lastDividend.toFixed(2)}` : "\u2014" },
|
|
@@ -18904,13 +18906,14 @@ var CloseButton3 = styled10__default.default.button`
|
|
|
18904
18906
|
var MainImageContainer = styled10__default.default.div`
|
|
18905
18907
|
position: relative;
|
|
18906
18908
|
flex: 1;
|
|
18909
|
+
min-height: 0;
|
|
18907
18910
|
display: flex;
|
|
18908
18911
|
align-items: center;
|
|
18909
18912
|
justify-content: center;
|
|
18910
|
-
padding:
|
|
18913
|
+
padding: 20px 20px 160px;
|
|
18911
18914
|
|
|
18912
18915
|
@media (max-width: 768px) {
|
|
18913
|
-
padding:
|
|
18916
|
+
padding: 10px 0 130px;
|
|
18914
18917
|
}
|
|
18915
18918
|
`;
|
|
18916
18919
|
var MainImage = styled10__default.default.img`
|
|
@@ -18922,8 +18925,11 @@ var MainImage = styled10__default.default.img`
|
|
|
18922
18925
|
opacity: ${(p) => p.$visible ? 1 : 0};
|
|
18923
18926
|
pointer-events: ${(p) => p.$visible ? "auto" : "none"};
|
|
18924
18927
|
transition: opacity 300ms ease;
|
|
18925
|
-
/*
|
|
18926
|
-
|
|
18928
|
+
/* All slides share the same absolute box so switching only crossfades opacity —
|
|
18929
|
+
no relative↔absolute size jump (the "grow then shrink" on navigation).
|
|
18930
|
+
The inset box excludes the bottom thumbnail strip so margin:auto centres the image
|
|
18931
|
+
in the space ABOVE the thumbnails (absolute positioning ignores the parent's padding,
|
|
18932
|
+
which otherwise let the image sink behind the thumbnails / "lean down"). */
|
|
18927
18933
|
position: absolute;
|
|
18928
18934
|
top: 24px;
|
|
18929
18935
|
left: 24px;
|
|
@@ -19117,9 +19123,11 @@ function PropertyPhotoGallery({
|
|
|
19117
19123
|
isOpen,
|
|
19118
19124
|
onClose,
|
|
19119
19125
|
startIndex = 0,
|
|
19126
|
+
startWithVideo = false,
|
|
19120
19127
|
title = "28 Derby Street, Vaucluse",
|
|
19121
19128
|
subtitle = "Elara \u2014 Luxury Harbour Residence",
|
|
19122
|
-
images
|
|
19129
|
+
images,
|
|
19130
|
+
videoUrl
|
|
19123
19131
|
}) {
|
|
19124
19132
|
const galleryImages = images?.length ? images : DEFAULT_IMAGES;
|
|
19125
19133
|
if (!isOpen) return null;
|
|
@@ -19128,16 +19136,19 @@ function PropertyPhotoGallery({
|
|
|
19128
19136
|
{
|
|
19129
19137
|
galleryImages,
|
|
19130
19138
|
startIndex,
|
|
19139
|
+
startWithVideo,
|
|
19131
19140
|
title,
|
|
19132
19141
|
subtitle,
|
|
19133
|
-
onClose
|
|
19142
|
+
onClose,
|
|
19143
|
+
videoUrl
|
|
19134
19144
|
},
|
|
19135
|
-
`${startIndex}-${galleryImages.length}`
|
|
19145
|
+
`${startIndex}-${galleryImages.length}-${startWithVideo}`
|
|
19136
19146
|
);
|
|
19137
19147
|
}
|
|
19138
|
-
function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose }) {
|
|
19148
|
+
function GalleryContent({ galleryImages, startIndex, startWithVideo, title, subtitle, onClose, videoUrl }) {
|
|
19139
19149
|
const [currentIndex, setCurrentIndex] = React5.useState(() => clampIndex(startIndex, galleryImages.length));
|
|
19140
19150
|
const [activeHotspotId, setActiveHotspotId] = React5.useState(null);
|
|
19151
|
+
const [showVideo, setShowVideo] = React5.useState(startWithVideo ?? false);
|
|
19141
19152
|
const sliderRef = React5.useRef(null);
|
|
19142
19153
|
const [isDragging, setIsDragging] = React5.useState(false);
|
|
19143
19154
|
const wasDraggingRef = React5.useRef(false);
|
|
@@ -19187,7 +19198,7 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
|
|
|
19187
19198
|
] }),
|
|
19188
19199
|
/* @__PURE__ */ jsxRuntime.jsx(CloseButton3, { onClick: onClose, "aria-label": "Close gallery", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", width: "22", height: "22", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 6l12 12M6 18L18 6" }) }) })
|
|
19189
19200
|
] }),
|
|
19190
|
-
/* @__PURE__ */ jsxRuntime.jsxs(SliderContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
19201
|
+
!showVideo && /* @__PURE__ */ jsxRuntime.jsxs(SliderContainer, { onClick: (event) => event.stopPropagation(), children: [
|
|
19191
19202
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
19192
19203
|
SliderTrack,
|
|
19193
19204
|
{
|
|
@@ -19250,7 +19261,21 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
|
|
|
19250
19261
|
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", width: "22", height: "22", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 18l-6-6 6-6" }) })
|
|
19251
19262
|
}
|
|
19252
19263
|
),
|
|
19253
|
-
|
|
19264
|
+
showVideo && videoUrl ? /* @__PURE__ */ jsxRuntime.jsx(GalleryVideoWrap, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
19265
|
+
"video",
|
|
19266
|
+
{
|
|
19267
|
+
autoPlay: true,
|
|
19268
|
+
loop: true,
|
|
19269
|
+
playsInline: true,
|
|
19270
|
+
muted: true,
|
|
19271
|
+
controls: true,
|
|
19272
|
+
onVolumeChange: (e) => {
|
|
19273
|
+
if (!e.currentTarget.muted) e.currentTarget.muted = true;
|
|
19274
|
+
},
|
|
19275
|
+
style: { objectFit: "contain", borderRadius: 12, boxShadow: "0 30px 80px rgba(0,0,0,0.55)" },
|
|
19276
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("source", { src: videoUrl, type: "video/mp4" })
|
|
19277
|
+
}
|
|
19278
|
+
) }) : galleryImages.map((image, idx) => /* @__PURE__ */ jsxRuntime.jsx(MainImage, { src: image.src, alt: image.alt, $visible: idx === currentIndex }, image.alt)),
|
|
19254
19279
|
galleryImages[currentIndex]?.hotspots?.map((hotspot) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
19255
19280
|
Hotspot,
|
|
19256
19281
|
{
|
|
@@ -19295,11 +19320,83 @@ function GalleryContent({ galleryImages, startIndex, title, subtitle, onClose })
|
|
|
19295
19320
|
]
|
|
19296
19321
|
}
|
|
19297
19322
|
),
|
|
19298
|
-
/* @__PURE__ */ jsxRuntime.
|
|
19323
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ThumbnailStrip, { onClick: (event) => event.stopPropagation(), children: [
|
|
19324
|
+
galleryImages.map((image, idx) => /* @__PURE__ */ jsxRuntime.jsx(Thumbnail3, { $active: !showVideo && idx === currentIndex, onClick: () => {
|
|
19325
|
+
setShowVideo(false);
|
|
19326
|
+
setCurrentIndex(idx);
|
|
19327
|
+
}, "aria-label": `Preview ${image.label}`, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: image.src, alt: image.alt }) }, image.alt)),
|
|
19328
|
+
videoUrl && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
19329
|
+
/* @__PURE__ */ jsxRuntime.jsx(ThumbnailDivider, {}),
|
|
19330
|
+
/* @__PURE__ */ jsxRuntime.jsxs(VideoBtn, { $active: showVideo, onClick: () => setShowVideo(true), children: [
|
|
19331
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
19332
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "2", y: "4", width: "14", height: "16", rx: "2" }),
|
|
19333
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 8l6-4v16l-6-4z" })
|
|
19334
|
+
] }),
|
|
19335
|
+
"Video"
|
|
19336
|
+
] })
|
|
19337
|
+
] })
|
|
19338
|
+
] })
|
|
19299
19339
|
]
|
|
19300
19340
|
}
|
|
19301
19341
|
);
|
|
19302
19342
|
}
|
|
19343
|
+
var GalleryVideoWrap = styled10__default.default.div`
|
|
19344
|
+
position: absolute;
|
|
19345
|
+
inset: 0;
|
|
19346
|
+
display: flex;
|
|
19347
|
+
align-items: center;
|
|
19348
|
+
justify-content: center;
|
|
19349
|
+
padding: 20px 20px 160px;
|
|
19350
|
+
|
|
19351
|
+
video {
|
|
19352
|
+
max-width: 90%;
|
|
19353
|
+
max-height: 100%;
|
|
19354
|
+
}
|
|
19355
|
+
|
|
19356
|
+
/* Property videos stay permanently muted — remove the volume + mute buttons
|
|
19357
|
+
from the native player (Chrome/Edge/Safari/iOS/Android). Firefox ignores
|
|
19358
|
+
these and is covered by the onVolumeChange force-mute fallback. */
|
|
19359
|
+
video::-webkit-media-controls-mute-button,
|
|
19360
|
+
video::-webkit-media-controls-volume-slider,
|
|
19361
|
+
video::-webkit-media-controls-volume-control-container {
|
|
19362
|
+
display: none !important;
|
|
19363
|
+
}
|
|
19364
|
+
|
|
19365
|
+
@media (max-width: 768px) {
|
|
19366
|
+
padding: 10px 0 130px;
|
|
19367
|
+
|
|
19368
|
+
video {
|
|
19369
|
+
max-width: 100%;
|
|
19370
|
+
}
|
|
19371
|
+
}
|
|
19372
|
+
`;
|
|
19373
|
+
var ThumbnailDivider = styled10__default.default.div`
|
|
19374
|
+
width: 1px;
|
|
19375
|
+
height: 48px;
|
|
19376
|
+
background: rgba(255, 255, 255, 0.15);
|
|
19377
|
+
flex-shrink: 0;
|
|
19378
|
+
align-self: center;
|
|
19379
|
+
`;
|
|
19380
|
+
var VideoBtn = styled10__default.default.button`
|
|
19381
|
+
display: flex;
|
|
19382
|
+
align-items: center;
|
|
19383
|
+
gap: 6px;
|
|
19384
|
+
padding: 8px 14px;
|
|
19385
|
+
border-radius: 8px;
|
|
19386
|
+
border: 1px solid ${(p) => p.$active ? "var(--color-accent, #E6C87E)" : "rgba(255, 255, 255, 0.2)"};
|
|
19387
|
+
background: ${(p) => p.$active ? "rgba(240, 185, 11, 0.15)" : "rgba(255, 255, 255, 0.08)"};
|
|
19388
|
+
color: ${(p) => p.$active ? "var(--color-accent, #E6C87E)" : "#fff"};
|
|
19389
|
+
font-size: 0.82rem;
|
|
19390
|
+
font-weight: 500;
|
|
19391
|
+
cursor: pointer;
|
|
19392
|
+
flex-shrink: 0;
|
|
19393
|
+
transition: all 0.2s ease;
|
|
19394
|
+
|
|
19395
|
+
&:hover {
|
|
19396
|
+
background: rgba(255, 255, 255, 0.15);
|
|
19397
|
+
border-color: rgba(255, 255, 255, 0.3);
|
|
19398
|
+
}
|
|
19399
|
+
`;
|
|
19303
19400
|
var slideIn2 = styled10.keyframes`
|
|
19304
19401
|
from { transform: translateX(110%); opacity: 0; }
|
|
19305
19402
|
to { transform: translateX(0); opacity: 1; }
|