@loafmarkets/ui 0.0.4 → 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.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",
@@ -1821,6 +1958,6 @@ var PropertySubheader = React5.forwardRef(
1821
1958
  );
1822
1959
  PropertySubheader.displayName = "PropertySubheader";
1823
1960
 
1824
- 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 };
1825
1962
  //# sourceMappingURL=index.mjs.map
1826
1963
  //# sourceMappingURL=index.mjs.map