@movebridge/react 0.0.1 → 0.1.0

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 CHANGED
@@ -340,7 +340,7 @@ declare function useWaitForTransaction(hash: string | null | undefined, options?
340
340
 
341
341
  /**
342
342
  * @movebridge/react - WalletButton component
343
- * Drop-in wallet connect button
343
+ * Drop-in wallet connect button with improved UX
344
344
  */
345
345
  /**
346
346
  * Props for WalletButton component
@@ -354,6 +354,7 @@ interface WalletButtonProps {
354
354
  /**
355
355
  * WalletButton component
356
356
  * Shows connect button when disconnected, address when connected
357
+ * Supports Razor, Nightly, and OKX wallets
357
358
  *
358
359
  * @example
359
360
  * ```tsx
@@ -365,7 +366,7 @@ declare function WalletButton({ className, connectText }: WalletButtonProps): re
365
366
 
366
367
  /**
367
368
  * @movebridge/react - WalletModal component
368
- * Modal for wallet selection
369
+ * Modal for wallet selection with Razor, Nightly, and OKX wallet support
369
370
  */
370
371
  /**
371
372
  * Props for WalletModal component
@@ -378,7 +379,7 @@ interface WalletModalProps {
378
379
  }
379
380
  /**
380
381
  * WalletModal component
381
- * Displays available wallets for selection
382
+ * Displays available wallets for selection with improved UX
382
383
  *
383
384
  * @example
384
385
  * ```tsx
package/dist/index.d.ts CHANGED
@@ -340,7 +340,7 @@ declare function useWaitForTransaction(hash: string | null | undefined, options?
340
340
 
341
341
  /**
342
342
  * @movebridge/react - WalletButton component
343
- * Drop-in wallet connect button
343
+ * Drop-in wallet connect button with improved UX
344
344
  */
345
345
  /**
346
346
  * Props for WalletButton component
@@ -354,6 +354,7 @@ interface WalletButtonProps {
354
354
  /**
355
355
  * WalletButton component
356
356
  * Shows connect button when disconnected, address when connected
357
+ * Supports Razor, Nightly, and OKX wallets
357
358
  *
358
359
  * @example
359
360
  * ```tsx
@@ -365,7 +366,7 @@ declare function WalletButton({ className, connectText }: WalletButtonProps): re
365
366
 
366
367
  /**
367
368
  * @movebridge/react - WalletModal component
368
- * Modal for wallet selection
369
+ * Modal for wallet selection with Razor, Nightly, and OKX wallet support
369
370
  */
370
371
  /**
371
372
  * Props for WalletModal component
@@ -378,7 +379,7 @@ interface WalletModalProps {
378
379
  }
379
380
  /**
380
381
  * WalletModal component
381
- * Displays available wallets for selection
382
+ * Displays available wallets for selection with improved UX
382
383
  *
383
384
  * @example
384
385
  * ```tsx
package/dist/index.js CHANGED
@@ -409,35 +409,48 @@ function useWaitForTransaction(hash, options) {
409
409
  }
410
410
 
411
411
  // src/components/WalletButton.tsx
412
- var import_react6 = require("react");
412
+ var import_react7 = require("react");
413
413
 
414
414
  // src/components/WalletModal.tsx
415
+ var import_react6 = require("react");
415
416
  var import_jsx_runtime2 = require("react/jsx-runtime");
416
417
  var WALLET_INFO = {
417
- petra: {
418
- name: "Petra",
419
- icon: "\u{1F98A}",
420
- description: "Recommended for Movement"
421
- },
422
- pontem: {
423
- name: "Pontem",
424
- icon: "\u{1F309}",
425
- description: "Multi-chain with Movement support"
418
+ razor: {
419
+ name: "Razor Wallet",
420
+ icon: "\u26A1",
421
+ description: "Secure wallet for Movement",
422
+ installUrl: "https://razorwallet.xyz/"
426
423
  },
427
424
  nightly: {
428
425
  name: "Nightly",
429
426
  icon: "\u{1F319}",
430
- description: "Movement & Aptos wallet"
427
+ description: "Multi-chain Movement wallet",
428
+ installUrl: "https://nightly.app/"
429
+ },
430
+ okx: {
431
+ name: "OKX Wallet",
432
+ icon: "\u{1F537}",
433
+ description: "OKX Web3 wallet",
434
+ installUrl: "https://www.okx.com/web3"
431
435
  }
432
436
  };
433
437
  function WalletModal({ open, onClose }) {
434
438
  const { wallets, connect, connecting } = useMovement();
439
+ const [connectingWallet, setConnectingWallet] = (0, import_react6.useState)(null);
435
440
  if (!open) return null;
436
441
  const handleConnect = async (wallet) => {
442
+ setConnectingWallet(wallet);
437
443
  try {
438
444
  await connect(wallet);
439
445
  onClose();
440
446
  } catch {
447
+ } finally {
448
+ setConnectingWallet(null);
449
+ }
450
+ };
451
+ const handleKeyDown = (e) => {
452
+ if (e.key === "Escape") {
453
+ onClose();
441
454
  }
442
455
  };
443
456
  const overlayStyles = {
@@ -493,88 +506,148 @@ function WalletModal({ open, onClose }) {
493
506
  marginBottom: "8px",
494
507
  transition: "all 0.2s ease"
495
508
  };
509
+ const walletButtonDisabledStyles = {
510
+ ...walletButtonStyles,
511
+ opacity: 0.6,
512
+ cursor: "not-allowed"
513
+ };
514
+ const walletButtonConnectingStyles = {
515
+ ...walletButtonStyles,
516
+ backgroundColor: "#f3f4f6",
517
+ borderColor: "#6366f1"
518
+ };
496
519
  const emptyStyles = {
497
520
  textAlign: "center",
498
521
  color: "#6b7280",
499
522
  padding: "20px"
500
523
  };
501
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: overlayStyles, onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: modalStyles, onClick: (e) => e.stopPropagation(), children: [
502
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: headerStyles, children: [
503
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { style: titleStyles, children: "Connect Wallet" }),
504
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { style: closeButtonStyles, onClick: onClose, children: "\xD7" })
505
- ] }),
506
- wallets.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: emptyStyles, children: [
507
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { marginBottom: "12px" }, children: "No wallets detected." }),
508
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { style: { marginBottom: "16px" }, children: [
509
- "Install a wallet that supports ",
510
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "Movement Network" }),
511
- ":"
512
- ] }),
513
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
514
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
515
- "a",
516
- {
517
- href: "https://petra.app/",
518
- target: "_blank",
519
- rel: "noopener noreferrer",
520
- style: {
521
- display: "inline-block",
522
- padding: "8px 16px",
523
- backgroundColor: "#4f46e5",
524
- color: "white",
525
- borderRadius: "6px",
526
- textDecoration: "none",
527
- fontSize: "14px"
528
- },
529
- children: "\u{1F98A} Get Petra (Recommended)"
530
- }
531
- ),
532
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
533
- "a",
524
+ const installLinkStyles = {
525
+ display: "inline-block",
526
+ padding: "10px 16px",
527
+ backgroundColor: "#6366f1",
528
+ color: "white",
529
+ borderRadius: "8px",
530
+ textDecoration: "none",
531
+ fontSize: "14px",
532
+ fontWeight: 500,
533
+ transition: "background-color 0.2s ease"
534
+ };
535
+ const getButtonStyle = (wallet) => {
536
+ if (connectingWallet === wallet) return walletButtonConnectingStyles;
537
+ if (connecting) return walletButtonDisabledStyles;
538
+ return walletButtonStyles;
539
+ };
540
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
541
+ "div",
542
+ {
543
+ style: overlayStyles,
544
+ onClick: onClose,
545
+ onKeyDown: handleKeyDown,
546
+ role: "dialog",
547
+ "aria-modal": "true",
548
+ "aria-labelledby": "wallet-modal-title",
549
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: modalStyles, onClick: (e) => e.stopPropagation(), children: [
550
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: headerStyles, children: [
551
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { id: "wallet-modal-title", style: titleStyles, children: "Connect Wallet" }),
552
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
553
+ "button",
554
+ {
555
+ style: closeButtonStyles,
556
+ onClick: onClose,
557
+ "aria-label": "Close wallet modal",
558
+ children: "\xD7"
559
+ }
560
+ )
561
+ ] }),
562
+ wallets.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: emptyStyles, children: [
563
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { marginBottom: "12px" }, children: "No wallets detected." }),
564
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { style: { marginBottom: "16px" }, children: [
565
+ "Install a wallet that supports ",
566
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "Movement Network" }),
567
+ ":"
568
+ ] }),
569
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "10px" }, children: [
570
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
571
+ "a",
572
+ {
573
+ href: WALLET_INFO.razor.installUrl,
574
+ target: "_blank",
575
+ rel: "noopener noreferrer",
576
+ style: installLinkStyles,
577
+ "aria-label": "Install Razor Wallet",
578
+ children: [
579
+ WALLET_INFO.razor.icon,
580
+ " Get ",
581
+ WALLET_INFO.razor.name
582
+ ]
583
+ }
584
+ ),
585
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
586
+ "a",
587
+ {
588
+ href: WALLET_INFO.nightly.installUrl,
589
+ target: "_blank",
590
+ rel: "noopener noreferrer",
591
+ style: installLinkStyles,
592
+ "aria-label": "Install Nightly Wallet",
593
+ children: [
594
+ WALLET_INFO.nightly.icon,
595
+ " Get ",
596
+ WALLET_INFO.nightly.name
597
+ ]
598
+ }
599
+ ),
600
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
601
+ "a",
602
+ {
603
+ href: WALLET_INFO.okx.installUrl,
604
+ target: "_blank",
605
+ rel: "noopener noreferrer",
606
+ style: installLinkStyles,
607
+ "aria-label": "Install OKX Wallet",
608
+ children: [
609
+ WALLET_INFO.okx.icon,
610
+ " Get ",
611
+ WALLET_INFO.okx.name
612
+ ]
613
+ }
614
+ )
615
+ ] })
616
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { role: "list", "aria-label": "Available wallets", children: wallets.map((wallet) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
617
+ "button",
534
618
  {
535
- href: "https://pontem.network/pontem-wallet",
536
- target: "_blank",
537
- rel: "noopener noreferrer",
538
- style: {
539
- display: "inline-block",
540
- padding: "8px 16px",
541
- backgroundColor: "#6366f1",
542
- color: "white",
543
- borderRadius: "6px",
544
- textDecoration: "none",
545
- fontSize: "14px"
546
- },
547
- children: "\u{1F309} Get Pontem"
548
- }
549
- )
619
+ style: getButtonStyle(wallet),
620
+ onClick: () => handleConnect(wallet),
621
+ disabled: connecting,
622
+ role: "listitem",
623
+ "aria-label": `Connect to ${WALLET_INFO[wallet].name}`,
624
+ children: [
625
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "24px" }, "aria-hidden": "true", children: connectingWallet === wallet ? "\u23F3" : WALLET_INFO[wallet].icon }),
626
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { textAlign: "left", flex: 1 }, children: [
627
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontWeight: 500 }, children: [
628
+ WALLET_INFO[wallet].name,
629
+ connectingWallet === wallet && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { marginLeft: "8px", fontSize: "12px", color: "#6366f1" }, children: "Connecting..." })
630
+ ] }),
631
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontSize: "12px", color: "#6b7280" }, children: WALLET_INFO[wallet].description })
632
+ ] })
633
+ ]
634
+ },
635
+ wallet
636
+ )) })
550
637
  ] })
551
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children: wallets.map((wallet) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
552
- "button",
553
- {
554
- style: walletButtonStyles,
555
- onClick: () => handleConnect(wallet),
556
- disabled: connecting,
557
- children: [
558
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: "24px" }, children: WALLET_INFO[wallet].icon }),
559
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { textAlign: "left" }, children: [
560
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children: WALLET_INFO[wallet].name }),
561
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontSize: "12px", color: "#6b7280" }, children: WALLET_INFO[wallet].description })
562
- ] })
563
- ]
564
- },
565
- wallet
566
- )) })
567
- ] }) });
638
+ }
639
+ );
568
640
  }
569
641
 
570
642
  // src/components/WalletButton.tsx
571
643
  var import_jsx_runtime3 = require("react/jsx-runtime");
572
644
  function truncateAddress(address) {
645
+ if (address.length <= 10) return address;
573
646
  return `${address.slice(0, 6)}...${address.slice(-4)}`;
574
647
  }
575
648
  function WalletButton({ className = "", connectText = "Connect Wallet" }) {
576
649
  const { address, connected, connecting, disconnect } = useMovement();
577
- const [modalOpen, setModalOpen] = (0, import_react6.useState)(false);
650
+ const [modalOpen, setModalOpen] = (0, import_react7.useState)(false);
578
651
  const baseStyles = {
579
652
  padding: "10px 20px",
580
653
  borderRadius: "8px",
@@ -582,7 +655,11 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
582
655
  cursor: "pointer",
583
656
  fontSize: "14px",
584
657
  fontWeight: 500,
585
- transition: "all 0.2s ease"
658
+ transition: "all 0.2s ease",
659
+ display: "inline-flex",
660
+ alignItems: "center",
661
+ justifyContent: "center",
662
+ gap: "8px"
586
663
  };
587
664
  const connectedStyles = {
588
665
  ...baseStyles,
@@ -594,15 +671,49 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
594
671
  backgroundColor: "#6366f1",
595
672
  color: "white"
596
673
  };
674
+ const connectingStyles = {
675
+ ...baseStyles,
676
+ backgroundColor: "#818cf8",
677
+ color: "white",
678
+ cursor: "wait"
679
+ };
597
680
  if (connected && address) {
598
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
681
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
599
682
  "button",
600
683
  {
601
684
  className,
602
685
  style: connectedStyles,
603
686
  onClick: disconnect,
604
687
  title: "Click to disconnect",
605
- children: truncateAddress(address)
688
+ "aria-label": `Connected as ${truncateAddress(address)}. Click to disconnect.`,
689
+ children: [
690
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: {
691
+ width: "8px",
692
+ height: "8px",
693
+ borderRadius: "50%",
694
+ backgroundColor: "#22c55e",
695
+ display: "inline-block"
696
+ }, "aria-hidden": "true" }),
697
+ truncateAddress(address)
698
+ ]
699
+ }
700
+ );
701
+ }
702
+ if (connecting) {
703
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
704
+ "button",
705
+ {
706
+ className,
707
+ style: connectingStyles,
708
+ disabled: true,
709
+ "aria-label": "Connecting to wallet",
710
+ children: [
711
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: {
712
+ display: "inline-block",
713
+ animation: "spin 1s linear infinite"
714
+ }, "aria-hidden": "true", children: "\u23F3" }),
715
+ "Connecting..."
716
+ ]
606
717
  }
607
718
  );
608
719
  }
@@ -613,8 +724,8 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
613
724
  className,
614
725
  style: disconnectedStyles,
615
726
  onClick: () => setModalOpen(true),
616
- disabled: connecting,
617
- children: connecting ? "Connecting..." : connectText
727
+ "aria-label": connectText,
728
+ children: connectText
618
729
  }
619
730
  ),
620
731
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(WalletModal, { open: modalOpen, onClose: () => setModalOpen(false) })
@@ -622,7 +733,7 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
622
733
  }
623
734
 
624
735
  // src/components/AddressDisplay.tsx
625
- var import_react7 = require("react");
736
+ var import_react8 = require("react");
626
737
  var import_jsx_runtime4 = require("react/jsx-runtime");
627
738
  function truncateAddress2(address, startChars = 6, endChars = 4) {
628
739
  if (address.length <= startChars + endChars + 3) {
@@ -636,8 +747,8 @@ function AddressDisplay({
636
747
  copyable = true,
637
748
  className = ""
638
749
  }) {
639
- const [copied, setCopied] = (0, import_react7.useState)(false);
640
- const handleCopy = (0, import_react7.useCallback)(async () => {
750
+ const [copied, setCopied] = (0, import_react8.useState)(false);
751
+ const handleCopy = (0, import_react8.useCallback)(async () => {
641
752
  try {
642
753
  await navigator.clipboard.writeText(address);
643
754
  setCopied(true);
package/dist/index.mjs CHANGED
@@ -375,35 +375,48 @@ function useWaitForTransaction(hash, options) {
375
375
  }
376
376
 
377
377
  // src/components/WalletButton.tsx
378
- import { useState as useState6 } from "react";
378
+ import { useState as useState7 } from "react";
379
379
 
380
380
  // src/components/WalletModal.tsx
381
+ import { useState as useState6 } from "react";
381
382
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
382
383
  var WALLET_INFO = {
383
- petra: {
384
- name: "Petra",
385
- icon: "\u{1F98A}",
386
- description: "Recommended for Movement"
387
- },
388
- pontem: {
389
- name: "Pontem",
390
- icon: "\u{1F309}",
391
- description: "Multi-chain with Movement support"
384
+ razor: {
385
+ name: "Razor Wallet",
386
+ icon: "\u26A1",
387
+ description: "Secure wallet for Movement",
388
+ installUrl: "https://razorwallet.xyz/"
392
389
  },
393
390
  nightly: {
394
391
  name: "Nightly",
395
392
  icon: "\u{1F319}",
396
- description: "Movement & Aptos wallet"
393
+ description: "Multi-chain Movement wallet",
394
+ installUrl: "https://nightly.app/"
395
+ },
396
+ okx: {
397
+ name: "OKX Wallet",
398
+ icon: "\u{1F537}",
399
+ description: "OKX Web3 wallet",
400
+ installUrl: "https://www.okx.com/web3"
397
401
  }
398
402
  };
399
403
  function WalletModal({ open, onClose }) {
400
404
  const { wallets, connect, connecting } = useMovement();
405
+ const [connectingWallet, setConnectingWallet] = useState6(null);
401
406
  if (!open) return null;
402
407
  const handleConnect = async (wallet) => {
408
+ setConnectingWallet(wallet);
403
409
  try {
404
410
  await connect(wallet);
405
411
  onClose();
406
412
  } catch {
413
+ } finally {
414
+ setConnectingWallet(null);
415
+ }
416
+ };
417
+ const handleKeyDown = (e) => {
418
+ if (e.key === "Escape") {
419
+ onClose();
407
420
  }
408
421
  };
409
422
  const overlayStyles = {
@@ -459,88 +472,148 @@ function WalletModal({ open, onClose }) {
459
472
  marginBottom: "8px",
460
473
  transition: "all 0.2s ease"
461
474
  };
475
+ const walletButtonDisabledStyles = {
476
+ ...walletButtonStyles,
477
+ opacity: 0.6,
478
+ cursor: "not-allowed"
479
+ };
480
+ const walletButtonConnectingStyles = {
481
+ ...walletButtonStyles,
482
+ backgroundColor: "#f3f4f6",
483
+ borderColor: "#6366f1"
484
+ };
462
485
  const emptyStyles = {
463
486
  textAlign: "center",
464
487
  color: "#6b7280",
465
488
  padding: "20px"
466
489
  };
467
- return /* @__PURE__ */ jsx2("div", { style: overlayStyles, onClick: onClose, children: /* @__PURE__ */ jsxs("div", { style: modalStyles, onClick: (e) => e.stopPropagation(), children: [
468
- /* @__PURE__ */ jsxs("div", { style: headerStyles, children: [
469
- /* @__PURE__ */ jsx2("h2", { style: titleStyles, children: "Connect Wallet" }),
470
- /* @__PURE__ */ jsx2("button", { style: closeButtonStyles, onClick: onClose, children: "\xD7" })
471
- ] }),
472
- wallets.length === 0 ? /* @__PURE__ */ jsxs("div", { style: emptyStyles, children: [
473
- /* @__PURE__ */ jsx2("p", { style: { marginBottom: "12px" }, children: "No wallets detected." }),
474
- /* @__PURE__ */ jsxs("p", { style: { marginBottom: "16px" }, children: [
475
- "Install a wallet that supports ",
476
- /* @__PURE__ */ jsx2("strong", { children: "Movement Network" }),
477
- ":"
478
- ] }),
479
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
480
- /* @__PURE__ */ jsx2(
481
- "a",
482
- {
483
- href: "https://petra.app/",
484
- target: "_blank",
485
- rel: "noopener noreferrer",
486
- style: {
487
- display: "inline-block",
488
- padding: "8px 16px",
489
- backgroundColor: "#4f46e5",
490
- color: "white",
491
- borderRadius: "6px",
492
- textDecoration: "none",
493
- fontSize: "14px"
494
- },
495
- children: "\u{1F98A} Get Petra (Recommended)"
496
- }
497
- ),
498
- /* @__PURE__ */ jsx2(
499
- "a",
490
+ const installLinkStyles = {
491
+ display: "inline-block",
492
+ padding: "10px 16px",
493
+ backgroundColor: "#6366f1",
494
+ color: "white",
495
+ borderRadius: "8px",
496
+ textDecoration: "none",
497
+ fontSize: "14px",
498
+ fontWeight: 500,
499
+ transition: "background-color 0.2s ease"
500
+ };
501
+ const getButtonStyle = (wallet) => {
502
+ if (connectingWallet === wallet) return walletButtonConnectingStyles;
503
+ if (connecting) return walletButtonDisabledStyles;
504
+ return walletButtonStyles;
505
+ };
506
+ return /* @__PURE__ */ jsx2(
507
+ "div",
508
+ {
509
+ style: overlayStyles,
510
+ onClick: onClose,
511
+ onKeyDown: handleKeyDown,
512
+ role: "dialog",
513
+ "aria-modal": "true",
514
+ "aria-labelledby": "wallet-modal-title",
515
+ children: /* @__PURE__ */ jsxs("div", { style: modalStyles, onClick: (e) => e.stopPropagation(), children: [
516
+ /* @__PURE__ */ jsxs("div", { style: headerStyles, children: [
517
+ /* @__PURE__ */ jsx2("h2", { id: "wallet-modal-title", style: titleStyles, children: "Connect Wallet" }),
518
+ /* @__PURE__ */ jsx2(
519
+ "button",
520
+ {
521
+ style: closeButtonStyles,
522
+ onClick: onClose,
523
+ "aria-label": "Close wallet modal",
524
+ children: "\xD7"
525
+ }
526
+ )
527
+ ] }),
528
+ wallets.length === 0 ? /* @__PURE__ */ jsxs("div", { style: emptyStyles, children: [
529
+ /* @__PURE__ */ jsx2("p", { style: { marginBottom: "12px" }, children: "No wallets detected." }),
530
+ /* @__PURE__ */ jsxs("p", { style: { marginBottom: "16px" }, children: [
531
+ "Install a wallet that supports ",
532
+ /* @__PURE__ */ jsx2("strong", { children: "Movement Network" }),
533
+ ":"
534
+ ] }),
535
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "10px" }, children: [
536
+ /* @__PURE__ */ jsxs(
537
+ "a",
538
+ {
539
+ href: WALLET_INFO.razor.installUrl,
540
+ target: "_blank",
541
+ rel: "noopener noreferrer",
542
+ style: installLinkStyles,
543
+ "aria-label": "Install Razor Wallet",
544
+ children: [
545
+ WALLET_INFO.razor.icon,
546
+ " Get ",
547
+ WALLET_INFO.razor.name
548
+ ]
549
+ }
550
+ ),
551
+ /* @__PURE__ */ jsxs(
552
+ "a",
553
+ {
554
+ href: WALLET_INFO.nightly.installUrl,
555
+ target: "_blank",
556
+ rel: "noopener noreferrer",
557
+ style: installLinkStyles,
558
+ "aria-label": "Install Nightly Wallet",
559
+ children: [
560
+ WALLET_INFO.nightly.icon,
561
+ " Get ",
562
+ WALLET_INFO.nightly.name
563
+ ]
564
+ }
565
+ ),
566
+ /* @__PURE__ */ jsxs(
567
+ "a",
568
+ {
569
+ href: WALLET_INFO.okx.installUrl,
570
+ target: "_blank",
571
+ rel: "noopener noreferrer",
572
+ style: installLinkStyles,
573
+ "aria-label": "Install OKX Wallet",
574
+ children: [
575
+ WALLET_INFO.okx.icon,
576
+ " Get ",
577
+ WALLET_INFO.okx.name
578
+ ]
579
+ }
580
+ )
581
+ ] })
582
+ ] }) : /* @__PURE__ */ jsx2("div", { role: "list", "aria-label": "Available wallets", children: wallets.map((wallet) => /* @__PURE__ */ jsxs(
583
+ "button",
500
584
  {
501
- href: "https://pontem.network/pontem-wallet",
502
- target: "_blank",
503
- rel: "noopener noreferrer",
504
- style: {
505
- display: "inline-block",
506
- padding: "8px 16px",
507
- backgroundColor: "#6366f1",
508
- color: "white",
509
- borderRadius: "6px",
510
- textDecoration: "none",
511
- fontSize: "14px"
512
- },
513
- children: "\u{1F309} Get Pontem"
514
- }
515
- )
585
+ style: getButtonStyle(wallet),
586
+ onClick: () => handleConnect(wallet),
587
+ disabled: connecting,
588
+ role: "listitem",
589
+ "aria-label": `Connect to ${WALLET_INFO[wallet].name}`,
590
+ children: [
591
+ /* @__PURE__ */ jsx2("span", { style: { fontSize: "24px" }, "aria-hidden": "true", children: connectingWallet === wallet ? "\u23F3" : WALLET_INFO[wallet].icon }),
592
+ /* @__PURE__ */ jsxs("div", { style: { textAlign: "left", flex: 1 }, children: [
593
+ /* @__PURE__ */ jsxs("div", { style: { fontWeight: 500 }, children: [
594
+ WALLET_INFO[wallet].name,
595
+ connectingWallet === wallet && /* @__PURE__ */ jsx2("span", { style: { marginLeft: "8px", fontSize: "12px", color: "#6366f1" }, children: "Connecting..." })
596
+ ] }),
597
+ /* @__PURE__ */ jsx2("div", { style: { fontSize: "12px", color: "#6b7280" }, children: WALLET_INFO[wallet].description })
598
+ ] })
599
+ ]
600
+ },
601
+ wallet
602
+ )) })
516
603
  ] })
517
- ] }) : /* @__PURE__ */ jsx2("div", { children: wallets.map((wallet) => /* @__PURE__ */ jsxs(
518
- "button",
519
- {
520
- style: walletButtonStyles,
521
- onClick: () => handleConnect(wallet),
522
- disabled: connecting,
523
- children: [
524
- /* @__PURE__ */ jsx2("span", { style: { fontSize: "24px" }, children: WALLET_INFO[wallet].icon }),
525
- /* @__PURE__ */ jsxs("div", { style: { textAlign: "left" }, children: [
526
- /* @__PURE__ */ jsx2("div", { children: WALLET_INFO[wallet].name }),
527
- /* @__PURE__ */ jsx2("div", { style: { fontSize: "12px", color: "#6b7280" }, children: WALLET_INFO[wallet].description })
528
- ] })
529
- ]
530
- },
531
- wallet
532
- )) })
533
- ] }) });
604
+ }
605
+ );
534
606
  }
535
607
 
536
608
  // src/components/WalletButton.tsx
537
609
  import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
538
610
  function truncateAddress(address) {
611
+ if (address.length <= 10) return address;
539
612
  return `${address.slice(0, 6)}...${address.slice(-4)}`;
540
613
  }
541
614
  function WalletButton({ className = "", connectText = "Connect Wallet" }) {
542
615
  const { address, connected, connecting, disconnect } = useMovement();
543
- const [modalOpen, setModalOpen] = useState6(false);
616
+ const [modalOpen, setModalOpen] = useState7(false);
544
617
  const baseStyles = {
545
618
  padding: "10px 20px",
546
619
  borderRadius: "8px",
@@ -548,7 +621,11 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
548
621
  cursor: "pointer",
549
622
  fontSize: "14px",
550
623
  fontWeight: 500,
551
- transition: "all 0.2s ease"
624
+ transition: "all 0.2s ease",
625
+ display: "inline-flex",
626
+ alignItems: "center",
627
+ justifyContent: "center",
628
+ gap: "8px"
552
629
  };
553
630
  const connectedStyles = {
554
631
  ...baseStyles,
@@ -560,15 +637,49 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
560
637
  backgroundColor: "#6366f1",
561
638
  color: "white"
562
639
  };
640
+ const connectingStyles = {
641
+ ...baseStyles,
642
+ backgroundColor: "#818cf8",
643
+ color: "white",
644
+ cursor: "wait"
645
+ };
563
646
  if (connected && address) {
564
- return /* @__PURE__ */ jsx3(
647
+ return /* @__PURE__ */ jsxs2(
565
648
  "button",
566
649
  {
567
650
  className,
568
651
  style: connectedStyles,
569
652
  onClick: disconnect,
570
653
  title: "Click to disconnect",
571
- children: truncateAddress(address)
654
+ "aria-label": `Connected as ${truncateAddress(address)}. Click to disconnect.`,
655
+ children: [
656
+ /* @__PURE__ */ jsx3("span", { style: {
657
+ width: "8px",
658
+ height: "8px",
659
+ borderRadius: "50%",
660
+ backgroundColor: "#22c55e",
661
+ display: "inline-block"
662
+ }, "aria-hidden": "true" }),
663
+ truncateAddress(address)
664
+ ]
665
+ }
666
+ );
667
+ }
668
+ if (connecting) {
669
+ return /* @__PURE__ */ jsxs2(
670
+ "button",
671
+ {
672
+ className,
673
+ style: connectingStyles,
674
+ disabled: true,
675
+ "aria-label": "Connecting to wallet",
676
+ children: [
677
+ /* @__PURE__ */ jsx3("span", { style: {
678
+ display: "inline-block",
679
+ animation: "spin 1s linear infinite"
680
+ }, "aria-hidden": "true", children: "\u23F3" }),
681
+ "Connecting..."
682
+ ]
572
683
  }
573
684
  );
574
685
  }
@@ -579,8 +690,8 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
579
690
  className,
580
691
  style: disconnectedStyles,
581
692
  onClick: () => setModalOpen(true),
582
- disabled: connecting,
583
- children: connecting ? "Connecting..." : connectText
693
+ "aria-label": connectText,
694
+ children: connectText
584
695
  }
585
696
  ),
586
697
  /* @__PURE__ */ jsx3(WalletModal, { open: modalOpen, onClose: () => setModalOpen(false) })
@@ -588,7 +699,7 @@ function WalletButton({ className = "", connectText = "Connect Wallet" }) {
588
699
  }
589
700
 
590
701
  // src/components/AddressDisplay.tsx
591
- import { useState as useState7, useCallback as useCallback5 } from "react";
702
+ import { useState as useState8, useCallback as useCallback5 } from "react";
592
703
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
593
704
  function truncateAddress2(address, startChars = 6, endChars = 4) {
594
705
  if (address.length <= startChars + endChars + 3) {
@@ -602,7 +713,7 @@ function AddressDisplay({
602
713
  copyable = true,
603
714
  className = ""
604
715
  }) {
605
- const [copied, setCopied] = useState7(false);
716
+ const [copied, setCopied] = useState8(false);
606
717
  const handleCopy = useCallback5(async () => {
607
718
  try {
608
719
  await navigator.clipboard.writeText(address);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@movebridge/react",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "React hooks and components for Movement Network",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -16,7 +16,7 @@
16
16
  "dist"
17
17
  ],
18
18
  "dependencies": {
19
- "@movebridge/core": "0.0.1"
19
+ "@movebridge/core": "0.1.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@testing-library/react": "^14.1.0",