@loafmarkets/ui 0.0.3 → 0.0.5
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 +23 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.js +141 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +141 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1227,6 +1227,143 @@ var PropertyNewsUpdates = React5.forwardRef(
|
|
|
1227
1227
|
}
|
|
1228
1228
|
);
|
|
1229
1229
|
PropertyNewsUpdates.displayName = "PropertyNewsUpdates";
|
|
1230
|
+
var PropertyCompareBar = React5.forwardRef(
|
|
1231
|
+
({
|
|
1232
|
+
className,
|
|
1233
|
+
addresses,
|
|
1234
|
+
selectedAddressId,
|
|
1235
|
+
onSelectAddress,
|
|
1236
|
+
compareLabel = "Compare",
|
|
1237
|
+
onCompareClick,
|
|
1238
|
+
compareIcon,
|
|
1239
|
+
...props
|
|
1240
|
+
}, ref) => {
|
|
1241
|
+
const normalizedAddresses = React5.useMemo(() => {
|
|
1242
|
+
return addresses.map(
|
|
1243
|
+
(option) => typeof option === "string" ? { id: option, label: option } : option
|
|
1244
|
+
);
|
|
1245
|
+
}, [addresses]);
|
|
1246
|
+
const hasAddresses = normalizedAddresses.length > 0;
|
|
1247
|
+
const firstAddressId = normalizedAddresses[0]?.id;
|
|
1248
|
+
const isControlled = selectedAddressId !== void 0;
|
|
1249
|
+
const [internalSelectedId, setInternalSelectedId] = React5.useState(
|
|
1250
|
+
() => isControlled ? void 0 : firstAddressId
|
|
1251
|
+
);
|
|
1252
|
+
const resolvedSelectedId = isControlled ? selectedAddressId : internalSelectedId;
|
|
1253
|
+
React5.useEffect(() => {
|
|
1254
|
+
if (!isControlled) {
|
|
1255
|
+
setInternalSelectedId((current) => {
|
|
1256
|
+
if (current != null && normalizedAddresses.some((option) => option.id === current)) {
|
|
1257
|
+
return current;
|
|
1258
|
+
}
|
|
1259
|
+
return firstAddressId;
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
}, [firstAddressId, isControlled, normalizedAddresses]);
|
|
1263
|
+
const selectedOption = normalizedAddresses.find((option) => option.id === resolvedSelectedId) ?? normalizedAddresses[0];
|
|
1264
|
+
const [isDropdownOpen, setIsDropdownOpen] = React5.useState(false);
|
|
1265
|
+
const dropdownRef = React5.useRef(null);
|
|
1266
|
+
React5.useEffect(() => {
|
|
1267
|
+
if (!isDropdownOpen) return;
|
|
1268
|
+
const handleClick = (event) => {
|
|
1269
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
1270
|
+
setIsDropdownOpen(false);
|
|
1271
|
+
}
|
|
1272
|
+
};
|
|
1273
|
+
const handleKey = (event) => {
|
|
1274
|
+
if (event.key === "Escape") {
|
|
1275
|
+
setIsDropdownOpen(false);
|
|
1276
|
+
}
|
|
1277
|
+
};
|
|
1278
|
+
document.addEventListener("mousedown", handleClick);
|
|
1279
|
+
document.addEventListener("keydown", handleKey);
|
|
1280
|
+
return () => {
|
|
1281
|
+
document.removeEventListener("mousedown", handleClick);
|
|
1282
|
+
document.removeEventListener("keydown", handleKey);
|
|
1283
|
+
};
|
|
1284
|
+
}, [isDropdownOpen]);
|
|
1285
|
+
const defaultCompareIcon = /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M4 4h7v7H4V4zm0 9h7v7H4v-7zm9-9h7v7h-7V4zm0 9h7v7h-7v-7z" }) });
|
|
1286
|
+
const handleAddressSelect = (addressId) => {
|
|
1287
|
+
if (!isControlled) {
|
|
1288
|
+
setInternalSelectedId(addressId);
|
|
1289
|
+
}
|
|
1290
|
+
onSelectAddress?.(addressId);
|
|
1291
|
+
setIsDropdownOpen(false);
|
|
1292
|
+
};
|
|
1293
|
+
return /* @__PURE__ */ jsxs(
|
|
1294
|
+
"div",
|
|
1295
|
+
{
|
|
1296
|
+
ref,
|
|
1297
|
+
className: cn(
|
|
1298
|
+
"flex w-full flex-col gap-3 rounded-[14px] border border-[#1a1f2b] bg-[#0f131c] px-4 py-3 text-white shadow-[0_18px_45px_rgba(0,0,0,0.55)] md:flex-row md:items-center md:gap-4",
|
|
1299
|
+
className
|
|
1300
|
+
),
|
|
1301
|
+
...props,
|
|
1302
|
+
children: [
|
|
1303
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex-1", ref: dropdownRef, children: [
|
|
1304
|
+
/* @__PURE__ */ jsxs(
|
|
1305
|
+
"button",
|
|
1306
|
+
{
|
|
1307
|
+
type: "button",
|
|
1308
|
+
disabled: !hasAddresses,
|
|
1309
|
+
onClick: () => setIsDropdownOpen((prev) => !prev),
|
|
1310
|
+
className: cn(
|
|
1311
|
+
"flex h-[42px] w-full items-center justify-between rounded-[10px] border border-[#202632] bg-[#181c27] px-4 text-left text-[15px] font-semibold text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.05)] transition hover:bg-[#1d222e] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-accent,#e6c87e)]",
|
|
1312
|
+
!hasAddresses && "text-white/40"
|
|
1313
|
+
),
|
|
1314
|
+
children: [
|
|
1315
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: selectedOption ? selectedOption.label : hasAddresses ? "Select address" : "No addresses available" }),
|
|
1316
|
+
/* @__PURE__ */ jsx("span", { className: "ml-3 flex items-center text-white/60 transition-transform", "aria-hidden": true, children: /* @__PURE__ */ jsx(
|
|
1317
|
+
"svg",
|
|
1318
|
+
{
|
|
1319
|
+
width: "16",
|
|
1320
|
+
height: "16",
|
|
1321
|
+
viewBox: "0 0 24 24",
|
|
1322
|
+
fill: "currentColor",
|
|
1323
|
+
className: cn("transition-transform", isDropdownOpen && "rotate-180"),
|
|
1324
|
+
children: /* @__PURE__ */ jsx("path", { d: "M7 10l5 5 5-5H7z" })
|
|
1325
|
+
}
|
|
1326
|
+
) })
|
|
1327
|
+
]
|
|
1328
|
+
}
|
|
1329
|
+
),
|
|
1330
|
+
isDropdownOpen && hasAddresses ? /* @__PURE__ */ jsx("div", { className: "absolute left-0 top-[calc(100%+8px)] z-20 w-full rounded-[12px] border border-[#1f2431] bg-[#161925] py-1 shadow-[0_25px_55px_rgba(0,0,0,0.65)] backdrop-blur-sm", children: normalizedAddresses.map((option) => {
|
|
1331
|
+
const active = option.id === resolvedSelectedId;
|
|
1332
|
+
return /* @__PURE__ */ jsx(
|
|
1333
|
+
"button",
|
|
1334
|
+
{
|
|
1335
|
+
type: "button",
|
|
1336
|
+
className: cn(
|
|
1337
|
+
"flex w-full items-center px-4 py-2 text-left text-[14px] text-white/80 transition hover:bg-white/5 hover:text-white",
|
|
1338
|
+
active && "text-white"
|
|
1339
|
+
),
|
|
1340
|
+
onClick: () => handleAddressSelect(option.id),
|
|
1341
|
+
children: option.label
|
|
1342
|
+
},
|
|
1343
|
+
option.id
|
|
1344
|
+
);
|
|
1345
|
+
}) }) : null
|
|
1346
|
+
] }),
|
|
1347
|
+
/* @__PURE__ */ jsxs(
|
|
1348
|
+
Button,
|
|
1349
|
+
{
|
|
1350
|
+
variant: "accentOutline",
|
|
1351
|
+
size: "sm",
|
|
1352
|
+
className: "flex w-full items-center justify-center gap-2 rounded-[10px] border-[var(--color-accent,#e6c87e)] bg-transparent px-4 py-2 text-[14px] font-semibold text-[var(--color-accent,#e6c87e)] shadow-[0_10px_25px_rgba(0,0,0,0.45)] transition hover:bg-[rgba(230,200,126,0.08)] md:w-max",
|
|
1353
|
+
onClick: onCompareClick,
|
|
1354
|
+
disabled: !hasAddresses,
|
|
1355
|
+
children: [
|
|
1356
|
+
/* @__PURE__ */ jsx("span", { className: "text-base", children: compareIcon ?? defaultCompareIcon }),
|
|
1357
|
+
compareLabel
|
|
1358
|
+
]
|
|
1359
|
+
}
|
|
1360
|
+
)
|
|
1361
|
+
]
|
|
1362
|
+
}
|
|
1363
|
+
);
|
|
1364
|
+
}
|
|
1365
|
+
);
|
|
1366
|
+
PropertyCompareBar.displayName = "PropertyCompareBar";
|
|
1230
1367
|
var clampPct = (pct) => Math.min(100, Math.max(0, pct));
|
|
1231
1368
|
var EditIcon = ({ className }) => /* @__PURE__ */ jsxs(
|
|
1232
1369
|
"svg",
|
|
@@ -1293,7 +1430,8 @@ var YourOrders = React5.forwardRef(
|
|
|
1293
1430
|
] }),
|
|
1294
1431
|
orders.length === 0 ? /* @__PURE__ */ jsx("div", { className: "py-10 text-center text-sm text-white/50", children: "No orders" }) : /* @__PURE__ */ jsx("div", { children: orders.map((order) => {
|
|
1295
1432
|
const sideClass = order.side === "buy" ? "text-[#0ecb81]" : "text-[#f6465d]";
|
|
1296
|
-
const filled = clampPct(order.filledPercent);
|
|
1433
|
+
const filled = clampPct(order.filledPercent ?? 0);
|
|
1434
|
+
const isCancelled = order.status?.toUpperCase() === "CANCELLED";
|
|
1297
1435
|
const canEditPrice = Boolean(onEditPrice);
|
|
1298
1436
|
const canEditAmount = Boolean(onEditAmount);
|
|
1299
1437
|
const canCancel = Boolean(onCancel);
|
|
@@ -1351,7 +1489,7 @@ var YourOrders = React5.forwardRef(
|
|
|
1351
1489
|
] }),
|
|
1352
1490
|
/* @__PURE__ */ jsx("div", { className: "mt-1 h-1 w-4/5 overflow-hidden rounded-sm bg-white/10", children: /* @__PURE__ */ jsx("div", { className: "h-full rounded-sm bg-[#C9A227]", style: { width: `${filled}%` } }) })
|
|
1353
1491
|
] }),
|
|
1354
|
-
/* @__PURE__ */ jsx("div", { className: "px-2 text-center", children: /* @__PURE__ */ jsx(
|
|
1492
|
+
/* @__PURE__ */ jsx("div", { className: "px-2 text-center", children: isCancelled ? /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center rounded border border-white/20 px-3 py-1 text-[0.78rem] uppercase tracking-wide text-[#f6465d]", children: "Cancelled" }) : /* @__PURE__ */ jsx(
|
|
1355
1493
|
"button",
|
|
1356
1494
|
{
|
|
1357
1495
|
type: "button",
|
|
@@ -1820,6 +1958,6 @@ var PropertySubheader = React5.forwardRef(
|
|
|
1820
1958
|
);
|
|
1821
1959
|
PropertySubheader.displayName = "PropertySubheader";
|
|
1822
1960
|
|
|
1823
|
-
export { Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, HousePositionSlider, Orderbook, PortfolioSummary, PriceChart, PropertyHeroHeader, PropertyNewsUpdates, PropertySubheader, PropertyTour, YourOrders, badgeVariants, buttonVariants };
|
|
1961
|
+
export { Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, HousePositionSlider, Orderbook, PortfolioSummary, PriceChart, PropertyCompareBar, PropertyHeroHeader, PropertyNewsUpdates, PropertySubheader, PropertyTour, YourOrders, badgeVariants, buttonVariants };
|
|
1824
1962
|
//# sourceMappingURL=index.mjs.map
|
|
1825
1963
|
//# sourceMappingURL=index.mjs.map
|