@loafmarkets/ui 0.1.143 → 0.1.145
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 +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +136 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +136 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -755,8 +755,11 @@ type PropertyOverviewProps = {
|
|
|
755
755
|
contractAddress?: string;
|
|
756
756
|
chain?: string;
|
|
757
757
|
percentageTokenized?: number | null;
|
|
758
|
+
volume24h?: number | null;
|
|
759
|
+
openOrdersValue?: number | null;
|
|
760
|
+
holderCount?: number | null;
|
|
758
761
|
};
|
|
759
|
-
declare function PropertyOverview({ propertyName, location, midPrice, onTradeClick, onPhotosClick, description: descriptionProp, tradeButtonLabel, images, galleryCategories, videoUrl, tokenName, landSizeSqm: landProp, buildingSizeSqm: buildingProp, features: featuresProp, propertyInfo: propertyInfoProp, overviewData, bedrooms, bathrooms, carSpaces, propertyTypeLabel, tokensIssued: tokensIssuedProp, isLoading, ticker, contractAddress, chain, percentageTokenized, }: PropertyOverviewProps): react_jsx_runtime.JSX.Element;
|
|
762
|
+
declare function PropertyOverview({ propertyName, location, midPrice, onTradeClick, onPhotosClick, description: descriptionProp, tradeButtonLabel, images, galleryCategories, videoUrl, tokenName, landSizeSqm: landProp, buildingSizeSqm: buildingProp, features: featuresProp, propertyInfo: propertyInfoProp, overviewData, bedrooms, bathrooms, carSpaces, propertyTypeLabel, tokensIssued: tokensIssuedProp, isLoading, ticker, contractAddress, chain, percentageTokenized, volume24h, openOrdersValue, holderCount, }: PropertyOverviewProps): react_jsx_runtime.JSX.Element;
|
|
760
763
|
|
|
761
764
|
type OfferStatus = 'active' | 'rejected' | 'expired' | 'historical' | 'pending';
|
|
762
765
|
type PropertyOffer = {
|
package/dist/index.d.ts
CHANGED
|
@@ -755,8 +755,11 @@ type PropertyOverviewProps = {
|
|
|
755
755
|
contractAddress?: string;
|
|
756
756
|
chain?: string;
|
|
757
757
|
percentageTokenized?: number | null;
|
|
758
|
+
volume24h?: number | null;
|
|
759
|
+
openOrdersValue?: number | null;
|
|
760
|
+
holderCount?: number | null;
|
|
758
761
|
};
|
|
759
|
-
declare function PropertyOverview({ propertyName, location, midPrice, onTradeClick, onPhotosClick, description: descriptionProp, tradeButtonLabel, images, galleryCategories, videoUrl, tokenName, landSizeSqm: landProp, buildingSizeSqm: buildingProp, features: featuresProp, propertyInfo: propertyInfoProp, overviewData, bedrooms, bathrooms, carSpaces, propertyTypeLabel, tokensIssued: tokensIssuedProp, isLoading, ticker, contractAddress, chain, percentageTokenized, }: PropertyOverviewProps): react_jsx_runtime.JSX.Element;
|
|
762
|
+
declare function PropertyOverview({ propertyName, location, midPrice, onTradeClick, onPhotosClick, description: descriptionProp, tradeButtonLabel, images, galleryCategories, videoUrl, tokenName, landSizeSqm: landProp, buildingSizeSqm: buildingProp, features: featuresProp, propertyInfo: propertyInfoProp, overviewData, bedrooms, bathrooms, carSpaces, propertyTypeLabel, tokensIssued: tokensIssuedProp, isLoading, ticker, contractAddress, chain, percentageTokenized, volume24h, openOrdersValue, holderCount, }: PropertyOverviewProps): react_jsx_runtime.JSX.Element;
|
|
760
763
|
|
|
761
764
|
type OfferStatus = 'active' | 'rejected' | 'expired' | 'historical' | 'pending';
|
|
762
765
|
type PropertyOffer = {
|
package/dist/index.js
CHANGED
|
@@ -8133,8 +8133,7 @@ var Track = styled19__default.default.div`
|
|
|
8133
8133
|
`;
|
|
8134
8134
|
var Slide = styled19__default.default.div`
|
|
8135
8135
|
min-width: 100%; position: relative; cursor: pointer;
|
|
8136
|
-
img { width: 100%;
|
|
8137
|
-
@media (max-width: 768px) { img { height: 280px; } }
|
|
8136
|
+
img { width: 100%; aspect-ratio: 16/9; object-fit: cover; border-radius: 8px; }
|
|
8138
8137
|
`;
|
|
8139
8138
|
var SlideCaption = styled19__default.default.div`
|
|
8140
8139
|
position: absolute; bottom: 0; left: 0; right: 0; padding: 1rem;
|
|
@@ -8324,7 +8323,10 @@ function PropertyOverview({
|
|
|
8324
8323
|
ticker,
|
|
8325
8324
|
contractAddress,
|
|
8326
8325
|
chain = "Base (Ethereum L2)",
|
|
8327
|
-
percentageTokenized
|
|
8326
|
+
percentageTokenized,
|
|
8327
|
+
volume24h,
|
|
8328
|
+
openOrdersValue,
|
|
8329
|
+
holderCount
|
|
8328
8330
|
}) {
|
|
8329
8331
|
const [isDescExpanded, setDescExpanded] = React5.useState(false);
|
|
8330
8332
|
const description = descriptionProp ?? overviewData?.description ?? DEFAULT_DESCRIPTION;
|
|
@@ -8361,7 +8363,7 @@ function PropertyOverview({
|
|
|
8361
8363
|
const tokenPriceValue = midPrice > 0 ? midPrice : null;
|
|
8362
8364
|
const weeklyRent = overviewData?.weeklyRent ?? 0;
|
|
8363
8365
|
const annualRent = weeklyRent * 52;
|
|
8364
|
-
|
|
8366
|
+
resolvedValuation && annualRent > 0 ? (annualRent / resolvedValuation * 100).toFixed(2) : null;
|
|
8365
8367
|
const monthlyCoupon = annualRent / 12;
|
|
8366
8368
|
const tokenMarketCap = tokenPriceValue && resolvedTokensIssued ? tokenPriceValue * resolvedTokensIssued : null;
|
|
8367
8369
|
const currentDividendYield = tokenMarketCap && monthlyCoupon > 0 ? (monthlyCoupon * 12 / tokenMarketCap * 100).toFixed(2) : null;
|
|
@@ -8377,11 +8379,19 @@ function PropertyOverview({
|
|
|
8377
8379
|
{ label: "Property Type", value: resolvedPropertyType ?? "\u2014" },
|
|
8378
8380
|
{ label: "Location", value: location || "\u2014" }
|
|
8379
8381
|
];
|
|
8382
|
+
const vol24hDollar = volume24h != null && tokenPriceValue ? volume24h * tokenPriceValue : null;
|
|
8383
|
+
const holdRatio = (() => {
|
|
8384
|
+
if (!tokenMarketCap || tokenMarketCap <= 0 || vol24hDollar == null) return null;
|
|
8385
|
+
const turnover = vol24hDollar / (tokenMarketCap / 2);
|
|
8386
|
+
const holdPct = Math.max(0, Math.min(100, (1 - turnover) * 100));
|
|
8387
|
+
return { holdPct, tradePct: +(100 - holdPct).toFixed(1) };
|
|
8388
|
+
})();
|
|
8380
8389
|
const tokenStats = [
|
|
8381
8390
|
{ label: "Token Price", value: isLoading && tokenPriceValue == null ? loadingSkeleton : tokenPriceValue ? `$${tokenPriceValue.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : "\u2014", gold: true },
|
|
8382
|
-
{ label: "
|
|
8383
|
-
{ label: "Dividend Yield", value: isLoading &&
|
|
8384
|
-
{ label: "
|
|
8391
|
+
{ label: "24h Volume", value: isLoading && vol24hDollar == null ? loadingSkeleton : vol24hDollar != null && vol24hDollar > 0 ? `$${Math.round(vol24hDollar).toLocaleString()}` : "\u2014" },
|
|
8392
|
+
{ label: "Current Dividend Yield", value: isLoading && currentDividendYield == null ? loadingSkeleton : currentDividendYield ? `${currentDividendYield}%` : "\u2014" },
|
|
8393
|
+
{ label: "Open Orders", value: isLoading && openOrdersValue == null ? loadingSkeleton : openOrdersValue != null && openOrdersValue > 0 ? `$${Math.round(openOrdersValue).toLocaleString()}` : "\u2014" },
|
|
8394
|
+
{ label: "Holders", value: isLoading && holderCount == null ? loadingSkeleton : holderCount != null ? holderCount.toLocaleString() : "\u2014" }
|
|
8385
8395
|
];
|
|
8386
8396
|
const propertyStats = [
|
|
8387
8397
|
{ label: "Offering Valuation", value: isLoading && resolvedValuation == null ? loadingSkeleton : resolvedValuation ? resolvedValuation >= 1e6 ? `$${(resolvedValuation / 1e6).toFixed(2)}M` : `$${resolvedValuation.toLocaleString()}` : "\u2014" },
|
|
@@ -8420,7 +8430,30 @@ function PropertyOverview({
|
|
|
8420
8430
|
tokenStats.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(StatRow, { $gold: !!item.gold, children: [
|
|
8421
8431
|
/* @__PURE__ */ jsxRuntime.jsx(StatLabel, { children: item.label }),
|
|
8422
8432
|
/* @__PURE__ */ jsxRuntime.jsx(StatValue, { $gold: !!item.gold, children: item.value })
|
|
8423
|
-
] }, item.label))
|
|
8433
|
+
] }, item.label)),
|
|
8434
|
+
holdRatio && /* @__PURE__ */ jsxRuntime.jsxs(HoldRatioWrap, { children: [
|
|
8435
|
+
/* @__PURE__ */ jsxRuntime.jsxs(HoldRatioTitle, { children: [
|
|
8436
|
+
/* @__PURE__ */ jsxRuntime.jsx(HoldRatioTitleText, { children: "Holding Ratio" }),
|
|
8437
|
+
/* @__PURE__ */ jsxRuntime.jsx(HoldRatioInfo, { "data-tip": "Proportion of token holders vs active traders over the last 24 hours, measured by trading volume against market capitalisation.", children: "?" })
|
|
8438
|
+
] }),
|
|
8439
|
+
/* @__PURE__ */ jsxRuntime.jsxs(HoldRatioHeader, { children: [
|
|
8440
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
8441
|
+
/* @__PURE__ */ jsxRuntime.jsx(HoldRatioLabel, { $side: "hold", children: "Holding " }),
|
|
8442
|
+
/* @__PURE__ */ jsxRuntime.jsxs(HoldRatioValue, { $side: "hold", children: [
|
|
8443
|
+
holdRatio.holdPct.toFixed(1),
|
|
8444
|
+
"%"
|
|
8445
|
+
] })
|
|
8446
|
+
] }),
|
|
8447
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
8448
|
+
/* @__PURE__ */ jsxRuntime.jsxs(HoldRatioValue, { $side: "trade", children: [
|
|
8449
|
+
holdRatio.tradePct,
|
|
8450
|
+
"%"
|
|
8451
|
+
] }),
|
|
8452
|
+
/* @__PURE__ */ jsxRuntime.jsx(HoldRatioLabel, { $side: "trade", children: " Trading" })
|
|
8453
|
+
] })
|
|
8454
|
+
] }),
|
|
8455
|
+
/* @__PURE__ */ jsxRuntime.jsx(HoldRatioTrack, { children: /* @__PURE__ */ jsxRuntime.jsx(HoldRatioFill, { $pct: holdRatio.holdPct }) })
|
|
8456
|
+
] })
|
|
8424
8457
|
] }),
|
|
8425
8458
|
/* @__PURE__ */ jsxRuntime.jsxs(StatsColumn, { children: [
|
|
8426
8459
|
/* @__PURE__ */ jsxRuntime.jsx(StatsColumnHeader, { children: "Property Fundamentals" }),
|
|
@@ -8809,6 +8842,101 @@ var ProtectionDesc = styled19__default.default.div`
|
|
|
8809
8842
|
color: rgba(255,255,255,0.5);
|
|
8810
8843
|
line-height: 1.5;
|
|
8811
8844
|
`;
|
|
8845
|
+
var HoldRatioWrap = styled19__default.default.div`
|
|
8846
|
+
display: flex;
|
|
8847
|
+
flex-direction: column;
|
|
8848
|
+
gap: 6px;
|
|
8849
|
+
padding: 0.75rem 0 0;
|
|
8850
|
+
margin-top: 0.5rem;
|
|
8851
|
+
border-top: 1px solid rgba(255,255,255,0.04);
|
|
8852
|
+
`;
|
|
8853
|
+
var HoldRatioTitle = styled19__default.default.div`
|
|
8854
|
+
display: flex;
|
|
8855
|
+
align-items: center;
|
|
8856
|
+
gap: 5px;
|
|
8857
|
+
`;
|
|
8858
|
+
var HoldRatioTitleText = styled19__default.default.span`
|
|
8859
|
+
font-size: 0.65rem;
|
|
8860
|
+
font-weight: 600;
|
|
8861
|
+
text-transform: uppercase;
|
|
8862
|
+
letter-spacing: 0.06em;
|
|
8863
|
+
color: rgba(255,255,255,0.4);
|
|
8864
|
+
`;
|
|
8865
|
+
var HoldRatioInfo = styled19__default.default.span`
|
|
8866
|
+
position: relative;
|
|
8867
|
+
display: inline-flex;
|
|
8868
|
+
align-items: center;
|
|
8869
|
+
justify-content: center;
|
|
8870
|
+
width: 13px;
|
|
8871
|
+
height: 13px;
|
|
8872
|
+
border-radius: 50%;
|
|
8873
|
+
border: 1px solid rgba(255,255,255,0.15);
|
|
8874
|
+
font-size: 0.5rem;
|
|
8875
|
+
font-weight: 700;
|
|
8876
|
+
color: rgba(255,255,255,0.3);
|
|
8877
|
+
cursor: help;
|
|
8878
|
+
flex-shrink: 0;
|
|
8879
|
+
|
|
8880
|
+
&::after {
|
|
8881
|
+
content: attr(data-tip);
|
|
8882
|
+
position: absolute;
|
|
8883
|
+
bottom: calc(100% + 6px);
|
|
8884
|
+
left: 0;
|
|
8885
|
+
width: max-content;
|
|
8886
|
+
max-width: 260px;
|
|
8887
|
+
padding: 8px 12px;
|
|
8888
|
+
border-radius: 6px;
|
|
8889
|
+
background: #1a1a1e;
|
|
8890
|
+
border: 1px solid rgba(255,255,255,0.1);
|
|
8891
|
+
color: rgba(255,255,255,0.7);
|
|
8892
|
+
font-size: 0.7rem;
|
|
8893
|
+
font-weight: 400;
|
|
8894
|
+
letter-spacing: 0;
|
|
8895
|
+
text-transform: none;
|
|
8896
|
+
line-height: 1.45;
|
|
8897
|
+
white-space: normal;
|
|
8898
|
+
pointer-events: none;
|
|
8899
|
+
opacity: 0;
|
|
8900
|
+
transition: opacity 0.15s;
|
|
8901
|
+
z-index: 10;
|
|
8902
|
+
}
|
|
8903
|
+
|
|
8904
|
+
&:hover::after {
|
|
8905
|
+
opacity: 1;
|
|
8906
|
+
}
|
|
8907
|
+
`;
|
|
8908
|
+
var HoldRatioHeader = styled19__default.default.div`
|
|
8909
|
+
display: flex;
|
|
8910
|
+
align-items: center;
|
|
8911
|
+
justify-content: space-between;
|
|
8912
|
+
`;
|
|
8913
|
+
var HoldRatioLabel = styled19__default.default.span`
|
|
8914
|
+
font-size: 0.7rem;
|
|
8915
|
+
font-weight: 600;
|
|
8916
|
+
text-transform: uppercase;
|
|
8917
|
+
letter-spacing: 0.05em;
|
|
8918
|
+
color: ${(p) => p.$side === "trade" ? "rgba(246, 70, 93, 0.6)" : "rgba(14, 203, 129, 0.6)"};
|
|
8919
|
+
`;
|
|
8920
|
+
var HoldRatioValue = styled19__default.default.span`
|
|
8921
|
+
font-size: 0.75rem;
|
|
8922
|
+
font-weight: 600;
|
|
8923
|
+
font-variant-numeric: tabular-nums;
|
|
8924
|
+
color: ${(p) => p.$side === "trade" ? "rgba(246, 70, 93, 0.7)" : "rgba(14, 203, 129, 0.7)"};
|
|
8925
|
+
`;
|
|
8926
|
+
var HoldRatioTrack = styled19__default.default.div`
|
|
8927
|
+
height: 6px;
|
|
8928
|
+
border-radius: 3px;
|
|
8929
|
+
background: rgba(246, 70, 93, 0.15);
|
|
8930
|
+
overflow: hidden;
|
|
8931
|
+
position: relative;
|
|
8932
|
+
`;
|
|
8933
|
+
var HoldRatioFill = styled19__default.default.div`
|
|
8934
|
+
height: 100%;
|
|
8935
|
+
width: ${(p) => p.$pct}%;
|
|
8936
|
+
border-radius: 3px;
|
|
8937
|
+
background: rgba(14, 203, 129, 0.35);
|
|
8938
|
+
transition: width 0.6s ease;
|
|
8939
|
+
`;
|
|
8812
8940
|
var STATUS_BG = {
|
|
8813
8941
|
active: "rgba(14,203,129,0.18)",
|
|
8814
8942
|
rejected: "rgba(246,70,93,0.18)",
|