@0xsequence/marketplace-sdk 0.9.0 → 0.10.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/.storybook/main.ts +63 -0
- package/.storybook/preview.ts +24 -0
- package/.storybook/vitest.setup.ts +6 -0
- package/CHANGELOG.md +77 -8
- package/dist/{CalendarIcon-DbQ7Vxcw.js → CalendarIcon-CqsuAuCm.js} +4 -51
- package/dist/CalendarIcon-CqsuAuCm.js.map +1 -0
- package/dist/{CollectibleCard-C8Ae64Ab.d.ts → CollectibleCard-Dd-CG6dE.d.ts} +8 -7
- package/dist/InfoIcon-v0w_Lu7t.js +53 -0
- package/dist/InfoIcon-v0w_Lu7t.js.map +1 -0
- package/dist/{_internal-BgWcRIak.js → _internal-C75gOSNo.js} +2 -10
- package/dist/_internal-C75gOSNo.js.map +1 -0
- package/dist/actionModal-CMUeVsFX.js +116 -0
- package/dist/actionModal-CMUeVsFX.js.map +1 -0
- package/dist/{alien_swap-B_76IMma.js → alien_swap-CYv6YlOF.js} +1 -1
- package/dist/{alien_swap-B_76IMma.js.map → alien_swap-CYv6YlOF.js.map} +1 -1
- package/dist/{api-DTIan01C.js → api-BiMGqWdz.js} +17 -34
- package/dist/api-BiMGqWdz.js.map +1 -0
- package/dist/{aqua-xyz-CMN_TFY5.js → aqua-xyz-Bzn5baeH.js} +1 -1
- package/dist/{aqua-xyz-CMN_TFY5.js.map → aqua-xyz-Bzn5baeH.js.map} +1 -1
- package/dist/{aura-Cye_TuHj.js → aura-DzIWh8WT.js} +1 -1
- package/dist/{aura-Cye_TuHj.js.map → aura-DzIWh8WT.js.map} +1 -1
- package/dist/base-DqaJPvfN.js +22 -0
- package/dist/base-DqaJPvfN.js.map +1 -0
- package/dist/{blur-DWDMyMpK.js → blur-DSH-Cbpj.js} +1 -1
- package/dist/{blur-DWDMyMpK.js.map → blur-DSH-Cbpj.js.map} +1 -1
- package/dist/{coinbase-ByA_XRB0.js → coinbase-Df8URNxq.js} +1 -1
- package/dist/{coinbase-ByA_XRB0.js.map → coinbase-Df8URNxq.js.map} +1 -1
- package/dist/{new-marketplace-types-Bfis0U4J.d.ts → create-config-DKJ-F0jc.d.ts} +402 -41
- package/dist/{wagmi-CDzEQbfk.js → create-config-fQ-jbJD1.js} +20 -10
- package/dist/create-config-fQ-jbJD1.js.map +1 -0
- package/dist/{element-b77CyXIZ.js → element-Cx6uJu5N.js} +1 -1
- package/dist/{element-b77CyXIZ.js.map → element-Cx6uJu5N.js.map} +1 -1
- package/dist/{foundation-DbOrKP9Y.js → foundation-D6U4aRLN.js} +1 -1
- package/dist/{foundation-DbOrKP9Y.js.map → foundation-D6U4aRLN.js.map} +1 -1
- package/dist/get-provider-CYYHfrlg.js +10 -0
- package/dist/get-provider-CYYHfrlg.js.map +1 -0
- package/dist/get-query-client-D19vvfJo.js +23 -0
- package/dist/get-query-client-D19vvfJo.js.map +1 -0
- package/dist/hooks-4pxIbLbM.js +4044 -0
- package/dist/hooks-4pxIbLbM.js.map +1 -0
- package/dist/{index-BL9RUSEK.d.ts → index-136YrWDH.d.ts} +1 -1
- package/dist/{index-D5v5iluA.d.ts → index-BAhaEfqY.d.ts} +1 -1
- package/dist/index-BKBin-rq.d.ts +979 -0
- package/dist/{index-BQsgAvtX.d.ts → index-BUWB_RXp.d.ts} +776 -570
- package/dist/{index-21LE7OhL.d.ts → index-BhVFc2rX.d.ts} +6 -3
- package/dist/{index-DXMfTZ1F.d.ts → index-C5aqo8xu.d.ts} +1 -1
- package/dist/{index-ByznONYE.d.ts → index-CKrYP7ot.d.ts} +20 -48
- package/dist/{index-DaE5ZNHb.d.ts → index-CUwMH7Ht.d.ts} +5 -5
- package/dist/{index-CLy8y5hm.d.ts → index-Cu70Lw-w.d.ts} +1 -1
- package/dist/index.css +414 -1
- package/dist/index.d.ts +8 -10
- package/dist/index.js +13 -9
- package/dist/{looks-rare-C1VqNcSM.js → looks-rare-ChBRBY-p.js} +1 -1
- package/dist/{looks-rare-C1VqNcSM.js.map → looks-rare-ChBRBY-p.js.map} +1 -1
- package/dist/{magic-eden-ea_AGCZr.js → magic-eden-D5U7N1xL.js} +1 -1
- package/dist/{magic-eden-ea_AGCZr.js.map → magic-eden-D5U7N1xL.js.map} +1 -1
- package/dist/{manifold-8y8J2sjT.js → manifold-CtLF52zU.js} +1 -1
- package/dist/{manifold-8y8J2sjT.js.map → manifold-CtLF52zU.js.map} +1 -1
- package/dist/{marketplace-nwnZv9Cb.js → marketplace-DmFiyBoS.js} +1 -1
- package/dist/{marketplace-nwnZv9Cb.js.map → marketplace-DmFiyBoS.js.map} +1 -1
- package/dist/{marketplace-logos-CSeGcPW4.js → marketplace-logos-Cd6W-qOq.js} +21 -21
- package/dist/{marketplace-logos-CSeGcPW4.js.map → marketplace-logos-Cd6W-qOq.js.map} +1 -1
- package/dist/{marketplace.gen-BSDIX7NZ.js → marketplace.gen-HpnpL5xU.js} +3 -3
- package/dist/marketplace.gen-HpnpL5xU.js.map +1 -0
- package/dist/{marketplaceConfig-C6X1SUik.js → marketplaceConfig-GQTTmihy.js} +3 -3
- package/dist/marketplaceConfig-GQTTmihy.js.map +1 -0
- package/dist/{mintify-LA68TzWg.js → mintify-Bi3Bce68.js} +1 -1
- package/dist/{mintify-LA68TzWg.js.map → mintify-Bi3Bce68.js.map} +1 -1
- package/dist/network-CGD0oKtS.js +15 -0
- package/dist/network-CGD0oKtS.js.map +1 -0
- package/dist/{nftx-D3Tc8nzd.js → nftx-BDQZjtkX.js} +1 -1
- package/dist/{nftx-D3Tc8nzd.js.map → nftx-BDQZjtkX.js.map} +1 -1
- package/dist/{okx-hbqg6oIJ.js → okx-D4meadLe.js} +1 -1
- package/dist/{okx-hbqg6oIJ.js.map → okx-D4meadLe.js.map} +1 -1
- package/dist/{open-sea-BccuK8-t.js → open-sea-DN0hgfVw.js} +1 -1
- package/dist/{open-sea-BccuK8-t.js.map → open-sea-DN0hgfVw.js.map} +1 -1
- package/dist/{primary-sale-C55ALnfQ.js → primary-sale-CmWxSfFQ.js} +1 -1
- package/dist/{primary-sale-C55ALnfQ.js.map → primary-sale-CmWxSfFQ.js.map} +1 -1
- package/dist/provider-DPGUA10G.js +125 -0
- package/dist/provider-DPGUA10G.js.map +1 -0
- package/dist/{queries-CUU65uYZ.js → queries-Ce_2othB.js} +165 -7
- package/dist/queries-Ce_2othB.js.map +1 -0
- package/dist/{rarible-BgTwwj9g.js → rarible-B0xlD88A.js} +1 -1
- package/dist/{rarible-BgTwwj9g.js.map → rarible-B0xlD88A.js.map} +1 -1
- package/dist/react/_internal/api/index.d.ts +2 -4
- package/dist/react/_internal/api/index.js +7 -4
- package/dist/react/_internal/databeat/index.d.ts +2 -73
- package/dist/react/_internal/databeat/index.js +4 -21
- package/dist/react/_internal/index.d.ts +2 -7
- package/dist/react/_internal/index.js +11 -6
- package/dist/react/_internal/wagmi/index.d.ts +2 -4
- package/dist/react/_internal/wagmi/index.js +5 -3
- package/dist/react/hooks/index.d.ts +12 -17
- package/dist/react/hooks/index.js +23 -19
- package/dist/react/hooks/options/index.d.ts +2 -3
- package/dist/react/hooks/options/index.js +12 -7
- package/dist/react/index.d.ts +12 -17
- package/dist/react/index.js +28 -19
- package/dist/react/queries/index.d.ts +9 -8
- package/dist/react/queries/index.js +20 -15
- package/dist/react/ssr/index.d.ts +7 -9
- package/dist/react/ssr/index.js +11 -6
- package/dist/react/ssr/index.js.map +1 -1
- package/dist/react/ui/components/marketplace-collectible-card/index.d.ts +3 -8
- package/dist/react/ui/components/marketplace-collectible-card/index.js +27 -18
- package/dist/react/ui/components/marketplace-collectible-card/utils/index.d.ts +2 -7
- package/dist/react/ui/components/marketplace-collectible-card/utils/index.js +11 -6
- package/dist/react/ui/components/marketplace-logos/index.d.ts +21 -21
- package/dist/react/ui/components/marketplace-logos/index.js +1 -1
- package/dist/react/ui/icons/index.js +13 -9
- package/dist/react/ui/index.d.ts +3 -8
- package/dist/react/ui/index.js +27 -18
- package/dist/react/ui/modals/_internal/components/actionModal/index.d.ts +2 -2
- package/dist/react/ui/modals/_internal/components/actionModal/index.js +23 -18
- package/dist/{react-DAIicQPT.js → react-DP0M2Wfm.js} +799 -4306
- package/dist/react-DP0M2Wfm.js.map +1 -0
- package/dist/{react-BbHBl6gg.css → react-DeDyTgo7.css} +1 -1
- package/dist/{react-BbHBl6gg.css.map → react-DeDyTgo7.css.map} +1 -1
- package/dist/{sequence-Do3kzb4J.js → sequence-BIrOVRXO.js} +1 -1
- package/dist/{sequence-Do3kzb4J.js.map → sequence-BIrOVRXO.js.map} +1 -1
- package/dist/{sudo-swap-B6vPKxBz.js → sudo-swap-BPMon-M5.js} +1 -1
- package/dist/{sudo-swap-B6vPKxBz.js.map → sudo-swap-BPMon-M5.js.map} +1 -1
- package/dist/{super-rare-eCm1SE6O.js → super-rare-kPN6Ua8i.js} +1 -1
- package/dist/{super-rare-eCm1SE6O.js.map → super-rare-kPN6Ua8i.js.map} +1 -1
- package/dist/{token-Da4TdyUk.js → token-CHSBPYVG.js} +1 -1
- package/dist/{token-Da4TdyUk.js.map → token-CHSBPYVG.js.map} +1 -1
- package/dist/{transaction-CcVViHEL.js → transaction-CnctdNzS.js} +3 -21
- package/dist/transaction-CnctdNzS.js.map +1 -0
- package/dist/types/index.d.ts +2 -3
- package/dist/types/index.js +2 -2
- package/dist/{types-DwWE6xOF.js → types-Yw2ywj6j.js} +1 -1
- package/dist/{types-DwWE6xOF.js.map → types-Yw2ywj6j.js.map} +1 -1
- package/dist/utils/abi/index.d.ts +4 -4
- package/dist/utils/abi/index.js +4 -4
- package/dist/utils/abi/marketplace/index.d.ts +1 -1
- package/dist/utils/abi/marketplace/index.js +1 -1
- package/dist/utils/abi/primary-sale/index.d.ts +1 -1
- package/dist/utils/abi/primary-sale/index.js +1 -1
- package/dist/utils/abi/token/index.d.ts +1 -1
- package/dist/utils/abi/token/index.js +1 -1
- package/dist/utils/index.d.ts +7 -8
- package/dist/utils/index.js +12 -9
- package/dist/{utils-CW2NA5KG.js → utils-9RXDgcBl.js} +4 -11
- package/dist/utils-9RXDgcBl.js.map +1 -0
- package/dist/{utils-BPYfgDSL.js → utils-DjVJ9tov.js} +5 -6
- package/dist/utils-DjVJ9tov.js.map +1 -0
- package/dist/wagmi-Do_KW5ke.js +0 -0
- package/dist/{x2y2-DD17tT91.js → x2y2-BLz-_Q2O.js} +1 -1
- package/dist/{x2y2-DD17tT91.js.map → x2y2-BLz-_Q2O.js.map} +1 -1
- package/dist/{zora-BpSG9UzS.js → zora-UGhKs-aL.js} +1 -1
- package/dist/{zora-BpSG9UzS.js.map → zora-UGhKs-aL.js.map} +1 -1
- package/eslint.config.mjs +4 -0
- package/package.json +27 -14
- package/postcss.config.mjs +6 -0
- package/src/index.css +5 -4
- package/src/index.ts +1 -0
- package/src/react/__tests__/provider.test.tsx +4 -3
- package/src/react/_internal/api/__mocks__/indexer.msw.ts +16 -0
- package/src/react/_internal/api/__mocks__/laos.msw.ts +387 -0
- package/src/react/_internal/api/__mocks__/marketplace.msw.ts +2 -0
- package/src/react/_internal/api/__tests__/laos-api.test.ts +756 -0
- package/src/react/_internal/api/laos-api.ts +3 -0
- package/src/react/_internal/api/marketplace.gen.ts +5 -3
- package/src/react/_internal/api/query-keys.ts +12 -4
- package/src/react/_internal/api/services.ts +2 -14
- package/src/react/_internal/databeat/index.ts +15 -14
- package/src/react/_internal/databeat/types.ts +22 -0
- package/src/react/_internal/databeat/utils.ts +26 -0
- package/src/react/_internal/utils.ts +4 -4
- package/src/react/_internal/wagmi/create-config.ts +28 -13
- package/src/react/_internal/wallet/wallet.ts +4 -4
- package/src/react/hooks/__tests__/useBalanceOfCollectible.laos.test.tsx +367 -0
- package/src/react/hooks/__tests__/useCheckoutOptions.test.tsx +158 -0
- package/src/react/hooks/__tests__/useCheckoutOptionsSalesContract.test.tsx +42 -65
- package/src/react/hooks/__tests__/useCollectionBalanceDetails.test.tsx +17 -0
- package/src/react/hooks/__tests__/useCollectionDetailsPolling.test.tsx +11 -3
- package/src/react/hooks/__tests__/useConvertPriceToUSD.test.tsx +3 -3
- package/src/react/hooks/__tests__/useCurrencyBalance.test.tsx +7 -3
- package/src/react/hooks/__tests__/useFilters.test.tsx +2 -2
- package/src/react/hooks/__tests__/useGetTokenRanges.test.tsx +111 -0
- package/src/react/hooks/__tests__/useListTokenMetadata.test.tsx +83 -57
- package/src/react/hooks/__tests__/useTransferTokens.test.tsx +469 -0
- package/src/react/hooks/index.ts +3 -1
- package/src/react/hooks/useCheckoutOptions.tsx +96 -0
- package/src/react/hooks/useCheckoutOptionsSalesContract.tsx +98 -57
- package/src/react/hooks/useCollectionBalanceDetails.tsx +95 -68
- package/src/react/hooks/useCollectionDetailsPolling.tsx +3 -7
- package/src/react/hooks/useComparePrices.tsx +90 -82
- package/src/react/hooks/useConvertPriceToUSD.tsx +85 -71
- package/src/react/hooks/useCurrencyBalance.tsx +132 -46
- package/src/react/hooks/useERC721SaleMintedTokens.tsx +8 -5
- package/src/react/hooks/useFilters.tsx +154 -111
- package/src/react/hooks/useGetCountOfPrimarySaleItems.tsx +48 -0
- package/src/react/hooks/useGetTokenRanges.tsx +83 -22
- package/src/react/hooks/useList1155ShopCardData.tsx +2 -0
- package/src/react/hooks/useList721ShopCardData.tsx +12 -7
- package/src/react/hooks/useListCollections.tsx +25 -25
- package/src/react/hooks/useListMarketCardData.tsx +2 -1
- package/src/react/hooks/useListPrimarySaleItems.tsx +66 -0
- package/src/react/hooks/useListTokenMetadata.ts +71 -0
- package/src/react/hooks/useOpenConnectModal.tsx +9 -0
- package/src/react/hooks/useTokenSaleDetailsBatch.tsx +3 -7
- package/src/react/hooks/useTokenSupplies.ts +81 -0
- package/src/react/hooks/useTransferTokens.tsx +2 -2
- package/src/react/provider.tsx +73 -9
- package/src/react/queries/__tests__/balanceOfCollectible.laos.test.ts +123 -0
- package/src/react/queries/__tests__/inventory.laos.test.ts +496 -0
- package/src/react/queries/balanceOfCollectible.ts +7 -4
- package/src/react/queries/checkoutOptions.ts +85 -0
- package/src/react/queries/checkoutOptionsSalesContract.ts +89 -0
- package/src/react/queries/collectionBalanceDetails.ts +92 -0
- package/src/react/queries/comparePrices.ts +108 -0
- package/src/react/queries/convertPriceToUSD.ts +92 -0
- package/src/react/queries/filters.ts +138 -0
- package/src/react/queries/getTokenRanges.ts +62 -0
- package/src/react/queries/index.ts +3 -0
- package/src/react/queries/inventory.ts +6 -0
- package/src/react/queries/listBalances.ts +4 -3
- package/src/react/queries/listCollections.ts +7 -3
- package/src/react/queries/listTokenMetadata.ts +2 -2
- package/src/react/queries/marketplaceConfig.ts +1 -1
- package/src/react/queries/primarySaleItems.ts +85 -0
- package/src/react/queries/primarySaleItemsCount.ts +64 -0
- package/src/react/queries/tokenSupplies.ts +93 -0
- package/src/react/ui/components/_internals/action-button/ActionButton.tsx +66 -66
- package/src/react/ui/components/_internals/action-button/__tests__/ActionButtonBody.test.tsx +22 -4
- package/src/react/ui/components/_internals/action-button/components/ActionButtonBody.tsx +5 -4
- package/src/react/ui/components/_internals/action-button/components/NonOwnerActions.tsx +3 -0
- package/src/react/ui/components/_internals/action-button/components/OwnerActions.tsx +4 -4
- package/src/react/ui/components/_internals/action-button/hooks/useActionButtonLogic.ts +13 -8
- package/src/react/ui/components/_internals/action-button/store.ts +44 -34
- package/src/react/ui/components/_internals/custom-select/CustomSelect.stories.tsx +582 -0
- package/src/react/ui/components/_internals/pill/Pill.stories.tsx +83 -0
- package/src/react/ui/components/marketplace-collectible-card/Footer.tsx +11 -4
- package/src/react/ui/components/marketplace-collectible-card/components/ActionButtonWrapper.tsx +7 -4
- package/src/react/ui/components/marketplace-collectible-card/types.ts +4 -3
- package/src/react/ui/components/marketplace-collectible-card/utils/supplyStatus.ts +4 -7
- package/src/react/ui/components/marketplace-collectible-card/variants/ShopCard.tsx +5 -1
- package/src/react/ui/components/marketplace-logos/marketplace-logos.stories.tsx +199 -0
- package/src/react/ui/components/media/Media.stories.tsx +642 -0
- package/src/react/ui/components/media/Media.tsx +24 -19
- package/src/react/ui/components/media/types.ts +6 -0
- package/src/react/ui/modals/BuyModal/__tests__/BuyModalRouter.test.tsx +15 -0
- package/src/react/ui/modals/BuyModal/__tests__/ERC1155ShopModal.test.tsx +6 -0
- package/src/react/ui/modals/BuyModal/__tests__/Modal1155.test.tsx +7 -1
- package/src/react/ui/modals/BuyModal/__tests__/store.test.ts +9 -1
- package/src/react/ui/modals/BuyModal/components/ERC1155QuantityModal.tsx +15 -8
- package/src/react/ui/modals/BuyModal/components/ERC1155ShopModal.tsx +3 -0
- package/src/react/ui/modals/BuyModal/hooks/__tests__/useERC1155Checkout.test.tsx +30 -27
- package/src/react/ui/modals/BuyModal/hooks/useCheckoutOptions.ts +2 -2
- package/src/react/ui/modals/BuyModal/hooks/useERC1155Checkout.ts +11 -2
- package/src/react/ui/modals/BuyModal/hooks/useERC721SalePaymentParams.ts +1 -1
- package/src/react/ui/modals/BuyModal/hooks/usePaymentModalParams.ts +7 -0
- package/src/react/ui/modals/BuyModal/index.tsx +9 -1
- package/src/react/ui/modals/BuyModal/store.ts +26 -0
- package/src/react/ui/modals/CreateListingModal/Modal.tsx +28 -11
- package/src/react/ui/modals/CreateListingModal/store.ts +3 -3
- package/src/react/ui/modals/MakeOfferModal/Modal.tsx +30 -13
- package/src/react/ui/modals/MakeOfferModal/store.ts +3 -3
- package/src/react/ui/modals/SellModal/Modal.tsx +11 -8
- package/src/react/ui/modals/SellModal/store.ts +3 -3
- package/src/react/ui/modals/TransferModal/__tests__/__snapshots__/store.test.ts.snap +17 -0
- package/src/react/ui/modals/TransferModal/__tests__/store.test.ts +366 -0
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/__tests__/useHandleTransfer.test.tsx +402 -0
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/_components/TokenQuantityInput.tsx +51 -48
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/_components/TransferButton.tsx +39 -47
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/_components/WalletAddressInput.tsx +9 -8
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/index.tsx +31 -35
- package/src/react/ui/modals/TransferModal/_views/enterWalletAddress/useHandleTransfer.tsx +19 -10
- package/src/react/ui/modals/TransferModal/index.tsx +28 -31
- package/src/react/ui/modals/TransferModal/messages.ts +1 -1
- package/src/react/ui/modals/TransferModal/store.ts +122 -0
- package/src/react/ui/modals/_internal/components/calendar/index.tsx +0 -1
- package/src/react/ui/modals/_internal/components/currencyImage/index.tsx +10 -14
- package/src/react/ui/modals/_internal/components/currencyOptionsSelect/__tests__/index.test.tsx +5 -2
- package/src/react/ui/modals/_internal/components/currencyOptionsSelect/index.tsx +23 -17
- package/src/react/ui/modals/_internal/components/expirationDateSelect/index.tsx +10 -10
- package/src/react/ui/modals/_internal/components/floorPriceText/__tests__/FloorPriceText.test.tsx +6 -6
- package/src/react/ui/modals/_internal/components/priceInput/__tests__/PriceInput.test.tsx +13 -5
- package/src/react/ui/modals/_internal/components/priceInput/index.tsx +41 -26
- package/src/react/ui/modals/_internal/components/quantityInput/__tests__/index.test.tsx +68 -59
- package/src/react/ui/modals/_internal/components/quantityInput/index.tsx +155 -20
- package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/__tests__/SelectWaasFeeOptions.test.tsx +339 -40
- package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/index.tsx +95 -101
- package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/store.ts +72 -14
- package/src/react/ui/modals/_internal/components/selectWaasFeeOptions/useWaasFeeOptionManager.tsx +29 -13
- package/src/react/ui/modals/_internal/components/tokenPreview/index.tsx +2 -2
- package/src/react/ui/modals/_internal/components/transactionDetails/index.tsx +2 -2
- package/src/react/ui/modals/_internal/components/transactionPreview/index.tsx +88 -89
- package/src/react/ui/modals/_internal/components/transactionStatusModal/__tests__/TransactionStatusModal.test.tsx +36 -10
- package/src/react/ui/modals/_internal/components/transactionStatusModal/index.tsx +32 -20
- package/src/react/ui/modals/_internal/components/transactionStatusModal/store.ts +91 -62
- package/src/react/ui/modals/_internal/components/waasFeeOptionsSelect/WaasFeeOptionsSelect.tsx +43 -44
- package/src/react/ui/modals/_internal/types.ts +2 -2
- package/src/types/sdk-config.ts +6 -1
- package/src/utils/network.ts +15 -0
- package/test/test-utils.tsx +2 -0
- package/vitest.shims.d.ts +2 -0
- package/vitest.storybook.config.js +33 -0
- package/dist/CalendarIcon-DbQ7Vxcw.js.map +0 -1
- package/dist/_internal-BgWcRIak.js.map +0 -1
- package/dist/api-DTIan01C.js.map +0 -1
- package/dist/builder-api-C_zj5mr3.d.ts +0 -12
- package/dist/index-BUVWziLP.d.ts +0 -60
- package/dist/index-COt10OgI.d.ts +0 -24
- package/dist/index-DPNWNa7t.d.ts +0 -414
- package/dist/index-DsfCs3-x.d.ts +0 -122
- package/dist/index-dUb6wb4Y.d.ts +0 -22
- package/dist/marketplace.gen-BSDIX7NZ.js.map +0 -1
- package/dist/marketplaceConfig-C6X1SUik.js.map +0 -1
- package/dist/queries-CUU65uYZ.js.map +0 -1
- package/dist/react-DAIicQPT.js.map +0 -1
- package/dist/transaction-CcVViHEL.js.map +0 -1
- package/dist/utils-BPYfgDSL.js.map +0 -1
- package/dist/utils-CW2NA5KG.js.map +0 -1
- package/dist/wagmi-CDzEQbfk.js.map +0 -1
- package/src/react/hooks/__tests__/useGetTokenSuppliesMap.test.tsx +0 -104
- package/src/react/hooks/useGetTokenSuppliesMap.tsx +0 -73
- package/src/react/hooks/useListPrimarySaleItems.ts +0 -102
- package/src/react/queries/getTokenSuppliesMap.ts +0 -77
- package/src/react/ui/modals/TransferModal/_store.ts +0 -66
- package/src/react/ui/modals/_internal/components/quantityInput/QuantityInputBase.tsx +0 -166
- package/src/react/ui/modals/_internal/stores/accountModal.ts +0 -3
- /package/dist/{abi-BKyRjVcZ.js → abi-BMvgNbKQ.js} +0 -0
- /package/dist/{index-C39K_8SG.d.ts → index-CD2bj_xW.d.ts} +0 -0
- /package/dist/{options-B4QN7Xou.js → options-BBBR8u_4.js} +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
1
3
|
import { createStore } from '@xstate/store';
|
|
2
4
|
import { useSelector } from '@xstate/store/react';
|
|
3
5
|
import type { CollectibleCardAction } from '../../../../../types';
|
|
@@ -9,10 +11,14 @@ type PendingAction = {
|
|
|
9
11
|
timestamp: number;
|
|
10
12
|
};
|
|
11
13
|
|
|
14
|
+
interface ActionButtonContext {
|
|
15
|
+
pendingAction: PendingAction | null;
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
export const actionButtonStore = createStore({
|
|
13
19
|
context: {
|
|
14
|
-
pendingAction: null
|
|
15
|
-
},
|
|
20
|
+
pendingAction: null,
|
|
21
|
+
} as ActionButtonContext,
|
|
16
22
|
on: {
|
|
17
23
|
setPendingAction: (
|
|
18
24
|
context,
|
|
@@ -37,39 +43,43 @@ export const actionButtonStore = createStore({
|
|
|
37
43
|
},
|
|
38
44
|
});
|
|
39
45
|
|
|
40
|
-
export const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
)
|
|
45
|
-
actionButtonStore.send({
|
|
46
|
-
type: 'setPendingAction',
|
|
47
|
-
action,
|
|
48
|
-
onPendingActionExecuted,
|
|
49
|
-
tokenId,
|
|
50
|
-
});
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// Selector hooks
|
|
54
|
-
export const usePendingAction = () =>
|
|
55
|
-
useSelector(actionButtonStore, (state) => state.context.pendingAction);
|
|
56
|
-
|
|
57
|
-
export const clearPendingAction = () => {
|
|
58
|
-
actionButtonStore.send({ type: 'clearPendingAction' });
|
|
59
|
-
};
|
|
46
|
+
export const useActionButtonStore = () => {
|
|
47
|
+
const pendingAction = useSelector(
|
|
48
|
+
actionButtonStore,
|
|
49
|
+
(state) => state.context.pendingAction,
|
|
50
|
+
);
|
|
60
51
|
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
return {
|
|
53
|
+
pendingAction,
|
|
54
|
+
setPendingAction: (
|
|
55
|
+
action: CollectibleCardAction.BUY | CollectibleCardAction.OFFER,
|
|
56
|
+
onPendingActionExecuted: () => void,
|
|
57
|
+
tokenId: string,
|
|
58
|
+
) => {
|
|
59
|
+
actionButtonStore.send({
|
|
60
|
+
type: 'setPendingAction',
|
|
61
|
+
action,
|
|
62
|
+
onPendingActionExecuted,
|
|
63
|
+
tokenId,
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
clearPendingAction: () => {
|
|
67
|
+
actionButtonStore.send({ type: 'clearPendingAction' });
|
|
68
|
+
},
|
|
69
|
+
executePendingAction: () => {
|
|
70
|
+
if (!pendingAction) return;
|
|
63
71
|
|
|
64
|
-
|
|
72
|
+
const { timestamp, callback } = pendingAction;
|
|
65
73
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
if (timestamp && callback) {
|
|
75
|
+
// Only execute if the pending action is less than 5 minutes old
|
|
76
|
+
if (
|
|
77
|
+
Date.now() - timestamp < 5 * 60 * 1000 &&
|
|
78
|
+
typeof callback === 'function'
|
|
79
|
+
) {
|
|
80
|
+
callback();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
};
|
|
75
85
|
};
|
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { expect, fn, userEvent, within } from 'storybook/test';
|
|
3
|
+
import { CustomSelect } from './CustomSelect';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof CustomSelect> = {
|
|
6
|
+
title: 'Internals/Custom Select',
|
|
7
|
+
component: CustomSelect,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'centered',
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component: `
|
|
13
|
+
A custom dropdown select component with support for string and ReactNode content. Includes keyboard navigation, disabled states, and customizable styling.
|
|
14
|
+
`,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
argTypes: {
|
|
19
|
+
items: {
|
|
20
|
+
control: 'object',
|
|
21
|
+
description: 'Array of selectable items',
|
|
22
|
+
},
|
|
23
|
+
placeholder: {
|
|
24
|
+
control: 'text',
|
|
25
|
+
description: 'Placeholder text when no item is selected',
|
|
26
|
+
},
|
|
27
|
+
disabled: {
|
|
28
|
+
control: 'boolean',
|
|
29
|
+
description: 'Whether the select is disabled',
|
|
30
|
+
},
|
|
31
|
+
onValueChange: {
|
|
32
|
+
action: 'value changed',
|
|
33
|
+
description: 'Callback when selection changes',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
decorators: [
|
|
37
|
+
(Story) => (
|
|
38
|
+
<div style={{ padding: '1rem', width: '300px' }}>
|
|
39
|
+
<Story />
|
|
40
|
+
</div>
|
|
41
|
+
),
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default meta;
|
|
46
|
+
type Story = StoryObj<typeof CustomSelect>;
|
|
47
|
+
|
|
48
|
+
const basicItems = [
|
|
49
|
+
{ value: 'option1', content: 'Option 1' },
|
|
50
|
+
{ value: 'option2', content: 'Option 2' },
|
|
51
|
+
{ value: 'option3', content: 'Option 3' },
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
const manyItems = [
|
|
55
|
+
{ value: 'apple', content: 'Apple' },
|
|
56
|
+
{ value: 'banana', content: 'Banana' },
|
|
57
|
+
{ value: 'cherry', content: 'Cherry' },
|
|
58
|
+
{ value: 'date', content: 'Date' },
|
|
59
|
+
{ value: 'elderberry', content: 'Elderberry' },
|
|
60
|
+
{ value: 'fig', content: 'Fig' },
|
|
61
|
+
{ value: 'grape', content: 'Grape' },
|
|
62
|
+
{ value: 'honeydew', content: 'Honeydew' },
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
const itemsWithDisabled = [
|
|
66
|
+
{ value: 'available1', content: 'Available Option 1' },
|
|
67
|
+
{ value: 'disabled1', content: 'Disabled Option 1', disabled: true },
|
|
68
|
+
{ value: 'available2', content: 'Available Option 2' },
|
|
69
|
+
{ value: 'disabled2', content: 'Disabled Option 2', disabled: true },
|
|
70
|
+
{ value: 'available3', content: 'Available Option 3' },
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
export const Default: Story = {
|
|
74
|
+
args: {
|
|
75
|
+
items: basicItems,
|
|
76
|
+
placeholder: 'Select an option',
|
|
77
|
+
backgroundColor: '#020000',
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const WithDefaultValue: Story = {
|
|
82
|
+
args: {
|
|
83
|
+
items: basicItems,
|
|
84
|
+
defaultValue: basicItems[1],
|
|
85
|
+
placeholder: 'Select an option',
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const Disabled: Story = {
|
|
90
|
+
args: {
|
|
91
|
+
items: basicItems,
|
|
92
|
+
placeholder: 'Select an option',
|
|
93
|
+
disabled: true,
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const ManyOptions: Story = {
|
|
98
|
+
args: {
|
|
99
|
+
items: manyItems,
|
|
100
|
+
placeholder: 'Choose a fruit',
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const WithDisabledItems: Story = {
|
|
105
|
+
args: {
|
|
106
|
+
items: itemsWithDisabled,
|
|
107
|
+
placeholder: 'Select an option',
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const CustomPlaceholder: Story = {
|
|
112
|
+
args: {
|
|
113
|
+
items: [
|
|
114
|
+
{ value: 'eth', content: 'Ethereum' },
|
|
115
|
+
{ value: 'btc', content: 'Bitcoin' },
|
|
116
|
+
{ value: 'ada', content: 'Cardano' },
|
|
117
|
+
],
|
|
118
|
+
placeholder: 'Choose cryptocurrency',
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export const WithReactNodeContent: Story = {
|
|
123
|
+
args: {
|
|
124
|
+
items: [
|
|
125
|
+
{
|
|
126
|
+
value: 'user1',
|
|
127
|
+
content: (
|
|
128
|
+
<div className="flex items-center gap-2">
|
|
129
|
+
<div className="h-4 w-4 rounded-full bg-blue-500" />
|
|
130
|
+
<span>John Doe</span>
|
|
131
|
+
</div>
|
|
132
|
+
),
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
value: 'user2',
|
|
136
|
+
content: (
|
|
137
|
+
<div className="flex items-center gap-2">
|
|
138
|
+
<div className="h-4 w-4 rounded-full bg-green-500" />
|
|
139
|
+
<span>Jane Smith</span>
|
|
140
|
+
</div>
|
|
141
|
+
),
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
value: 'user3',
|
|
145
|
+
content: (
|
|
146
|
+
<div className="flex items-center gap-2">
|
|
147
|
+
<div className="h-4 w-4 rounded-full bg-red-500" />
|
|
148
|
+
<span>Bob Johnson</span>
|
|
149
|
+
</div>
|
|
150
|
+
),
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
placeholder: 'Select a user',
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Showcase different configurations
|
|
158
|
+
export const SelectShowcase: Story = {
|
|
159
|
+
render: () => (
|
|
160
|
+
<div className="space-y-4">
|
|
161
|
+
<div>
|
|
162
|
+
<h3 className="mb-2 font-medium text-sm">Basic Select</h3>
|
|
163
|
+
<CustomSelect items={basicItems} placeholder="Select an option" />
|
|
164
|
+
</div>
|
|
165
|
+
<div>
|
|
166
|
+
<h3 className="mb-2 font-medium text-sm">With Default Value</h3>
|
|
167
|
+
<CustomSelect
|
|
168
|
+
items={basicItems}
|
|
169
|
+
defaultValue={basicItems[0]}
|
|
170
|
+
placeholder="Select an option"
|
|
171
|
+
/>
|
|
172
|
+
</div>
|
|
173
|
+
<div>
|
|
174
|
+
<h3 className="mb-2 font-medium text-sm">Disabled</h3>
|
|
175
|
+
<CustomSelect
|
|
176
|
+
items={basicItems}
|
|
177
|
+
placeholder="Select an option"
|
|
178
|
+
disabled={true}
|
|
179
|
+
/>
|
|
180
|
+
</div>
|
|
181
|
+
<div>
|
|
182
|
+
<h3 className="mb-2 font-medium text-sm">With Some Disabled Items</h3>
|
|
183
|
+
<CustomSelect
|
|
184
|
+
items={itemsWithDisabled}
|
|
185
|
+
placeholder="Select an option"
|
|
186
|
+
/>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
),
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
// ========================================
|
|
193
|
+
// INTERACTION TESTS - Hidden from UI
|
|
194
|
+
// ========================================
|
|
195
|
+
|
|
196
|
+
export const BasicInteractionTest: Story = {
|
|
197
|
+
tags: ['!dev', '!autodocs'],
|
|
198
|
+
args: {
|
|
199
|
+
items: basicItems,
|
|
200
|
+
placeholder: 'Select an option',
|
|
201
|
+
onValueChange: fn(),
|
|
202
|
+
testId: 'basic-select',
|
|
203
|
+
},
|
|
204
|
+
play: async ({ args, canvasElement, step }) => {
|
|
205
|
+
const canvas = within(canvasElement);
|
|
206
|
+
const body = within(document.body);
|
|
207
|
+
|
|
208
|
+
await step('Verify initial render with placeholder', async () => {
|
|
209
|
+
const trigger = canvas.getByTestId('basic-select-trigger');
|
|
210
|
+
await expect(trigger).toBeInTheDocument();
|
|
211
|
+
await expect(trigger).toHaveTextContent('Select an option');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
await step('Open dropdown by clicking trigger', async () => {
|
|
215
|
+
const trigger = canvas.getByTestId('basic-select-trigger');
|
|
216
|
+
await userEvent.click(trigger);
|
|
217
|
+
|
|
218
|
+
// Content is rendered in a portal, so search in body
|
|
219
|
+
const content = await body.findByTestId('basic-select-content');
|
|
220
|
+
await expect(content).toBeInTheDocument();
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
await step('Verify all options are visible', async () => {
|
|
224
|
+
for (const item of basicItems) {
|
|
225
|
+
const option = body.getByTestId(`basic-select-option-${item.value}`);
|
|
226
|
+
await expect(option).toBeInTheDocument();
|
|
227
|
+
await expect(option).toHaveTextContent(item.content as string);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
await step('Select an option and verify callback', async () => {
|
|
232
|
+
const optionToSelect = body.getByTestId('basic-select-option-option2');
|
|
233
|
+
await userEvent.click(optionToSelect);
|
|
234
|
+
|
|
235
|
+
await expect(args.onValueChange).toHaveBeenCalledWith('option2');
|
|
236
|
+
|
|
237
|
+
// Verify selected option is displayed in trigger
|
|
238
|
+
const trigger = canvas.getByTestId('basic-select-trigger');
|
|
239
|
+
await expect(trigger).toHaveTextContent('Option 2');
|
|
240
|
+
});
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
export const DefaultValueTest: Story = {
|
|
245
|
+
tags: ['!dev', '!autodocs'],
|
|
246
|
+
args: {
|
|
247
|
+
items: basicItems,
|
|
248
|
+
defaultValue: basicItems[1], // Option 2
|
|
249
|
+
placeholder: 'Select an option',
|
|
250
|
+
onValueChange: fn(),
|
|
251
|
+
testId: 'default-value-select',
|
|
252
|
+
},
|
|
253
|
+
play: async ({ canvasElement, step }) => {
|
|
254
|
+
const canvas = within(canvasElement);
|
|
255
|
+
const body = within(document.body);
|
|
256
|
+
|
|
257
|
+
await step('Verify default value is displayed', async () => {
|
|
258
|
+
const trigger = canvas.getByTestId('default-value-select-trigger');
|
|
259
|
+
await expect(trigger).toBeInTheDocument();
|
|
260
|
+
await expect(trigger).toHaveTextContent('Option 2');
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
await step('Open dropdown and verify default selection', async () => {
|
|
264
|
+
const trigger = canvas.getByTestId('default-value-select-trigger');
|
|
265
|
+
await userEvent.click(trigger);
|
|
266
|
+
|
|
267
|
+
const selectedOption = await body.findByTestId(
|
|
268
|
+
'default-value-select-option-option2',
|
|
269
|
+
);
|
|
270
|
+
await expect(selectedOption).toBeInTheDocument();
|
|
271
|
+
// Note: The visual indication of selection would depend on the component's styling
|
|
272
|
+
});
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
export const DisabledStateTest: Story = {
|
|
277
|
+
tags: ['!dev', '!autodocs'],
|
|
278
|
+
args: {
|
|
279
|
+
items: basicItems,
|
|
280
|
+
placeholder: 'Select an option',
|
|
281
|
+
disabled: true,
|
|
282
|
+
onValueChange: fn(),
|
|
283
|
+
testId: 'disabled-select',
|
|
284
|
+
},
|
|
285
|
+
play: async ({ args, canvasElement, step }) => {
|
|
286
|
+
const canvas = within(canvasElement);
|
|
287
|
+
const body = within(document.body);
|
|
288
|
+
|
|
289
|
+
await step('Verify disabled trigger cannot be clicked', async () => {
|
|
290
|
+
const trigger = canvas.getByTestId('disabled-select-trigger');
|
|
291
|
+
await expect(trigger).toBeInTheDocument();
|
|
292
|
+
await expect(trigger).toBeDisabled();
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
await step('Attempt to click disabled trigger', async () => {
|
|
296
|
+
const trigger = canvas.getByTestId('disabled-select-trigger');
|
|
297
|
+
await userEvent.click(trigger);
|
|
298
|
+
|
|
299
|
+
// Dropdown should not open
|
|
300
|
+
const content = body.queryByTestId('disabled-select-content');
|
|
301
|
+
await expect(content).not.toBeInTheDocument();
|
|
302
|
+
|
|
303
|
+
// Callback should not be called
|
|
304
|
+
await expect(args.onValueChange).not.toHaveBeenCalled();
|
|
305
|
+
});
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
export const DisabledItemsTest: Story = {
|
|
310
|
+
tags: ['!dev', '!autodocs'],
|
|
311
|
+
args: {
|
|
312
|
+
items: itemsWithDisabled,
|
|
313
|
+
placeholder: 'Select an option',
|
|
314
|
+
onValueChange: fn(),
|
|
315
|
+
testId: 'disabled-items-select',
|
|
316
|
+
},
|
|
317
|
+
play: async ({ args, canvasElement, step }) => {
|
|
318
|
+
const canvas = within(canvasElement);
|
|
319
|
+
const body = within(document.body);
|
|
320
|
+
|
|
321
|
+
await step('Open dropdown', async () => {
|
|
322
|
+
const trigger = canvas.getByTestId('disabled-items-select-trigger');
|
|
323
|
+
await userEvent.click(trigger);
|
|
324
|
+
|
|
325
|
+
const content = await body.findByTestId('disabled-items-select-content');
|
|
326
|
+
await expect(content).toBeInTheDocument();
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
await step('Verify disabled items cannot be selected', async () => {
|
|
330
|
+
const disabledOption = body.getByTestId(
|
|
331
|
+
'disabled-items-select-option-disabled1',
|
|
332
|
+
);
|
|
333
|
+
await expect(disabledOption).toBeInTheDocument();
|
|
334
|
+
|
|
335
|
+
// Verify disabled option has disabled attributes
|
|
336
|
+
await expect(disabledOption).toHaveAttribute('data-disabled', '');
|
|
337
|
+
|
|
338
|
+
// Try to click disabled option (this should not work due to pointer-events: none)
|
|
339
|
+
try {
|
|
340
|
+
await userEvent.click(disabledOption);
|
|
341
|
+
} catch (error) {
|
|
342
|
+
// Expected to fail due to pointer-events: none
|
|
343
|
+
expect((error as Error).message).toContain('pointer-events: none');
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Should not trigger callback for disabled item
|
|
347
|
+
await expect(args.onValueChange).not.toHaveBeenCalledWith('disabled1');
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
await step('Verify enabled items can be selected', async () => {
|
|
351
|
+
const enabledOption = body.getByTestId(
|
|
352
|
+
'disabled-items-select-option-available1',
|
|
353
|
+
);
|
|
354
|
+
await userEvent.click(enabledOption);
|
|
355
|
+
|
|
356
|
+
await expect(args.onValueChange).toHaveBeenCalledWith('available1');
|
|
357
|
+
});
|
|
358
|
+
},
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
export const ReactNodeContentTest: Story = {
|
|
362
|
+
tags: ['!dev', '!autodocs'],
|
|
363
|
+
args: {
|
|
364
|
+
items: [
|
|
365
|
+
{
|
|
366
|
+
value: 'user1',
|
|
367
|
+
content: (
|
|
368
|
+
<div className="flex items-center gap-2">
|
|
369
|
+
<div className="h-4 w-4 rounded-full bg-blue-500" />
|
|
370
|
+
<span>John Doe</span>
|
|
371
|
+
</div>
|
|
372
|
+
),
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
value: 'user2',
|
|
376
|
+
content: (
|
|
377
|
+
<div className="flex items-center gap-2">
|
|
378
|
+
<div className="h-4 w-4 rounded-full bg-green-500" />
|
|
379
|
+
<span>Jane Smith</span>
|
|
380
|
+
</div>
|
|
381
|
+
),
|
|
382
|
+
},
|
|
383
|
+
],
|
|
384
|
+
placeholder: 'Select a user',
|
|
385
|
+
onValueChange: fn(),
|
|
386
|
+
testId: 'react-node-select',
|
|
387
|
+
},
|
|
388
|
+
play: async ({ args, canvasElement, step }) => {
|
|
389
|
+
const canvas = within(canvasElement);
|
|
390
|
+
const body = within(document.body);
|
|
391
|
+
|
|
392
|
+
await step('Open dropdown with ReactNode content', async () => {
|
|
393
|
+
const trigger = canvas.getByTestId('react-node-select-trigger');
|
|
394
|
+
await userEvent.click(trigger);
|
|
395
|
+
|
|
396
|
+
const content = await body.findByTestId('react-node-select-content');
|
|
397
|
+
await expect(content).toBeInTheDocument();
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
await step('Verify ReactNode content is rendered', async () => {
|
|
401
|
+
const user1Option = body.getByTestId(
|
|
402
|
+
'react-node-select-option-content-user1',
|
|
403
|
+
);
|
|
404
|
+
await expect(user1Option).toBeInTheDocument();
|
|
405
|
+
|
|
406
|
+
const user2Option = body.getByTestId(
|
|
407
|
+
'react-node-select-option-content-user2',
|
|
408
|
+
);
|
|
409
|
+
await expect(user2Option).toBeInTheDocument();
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
await step('Select ReactNode option', async () => {
|
|
413
|
+
const user1Option = body.getByTestId('react-node-select-option-user1');
|
|
414
|
+
await userEvent.click(user1Option);
|
|
415
|
+
|
|
416
|
+
await expect(args.onValueChange).toHaveBeenCalledWith('user1');
|
|
417
|
+
});
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
export const KeyboardNavigationTest: Story = {
|
|
422
|
+
tags: ['!dev', '!autodocs'],
|
|
423
|
+
args: {
|
|
424
|
+
items: basicItems,
|
|
425
|
+
placeholder: 'Select an option',
|
|
426
|
+
onValueChange: fn(),
|
|
427
|
+
testId: 'keyboard-select',
|
|
428
|
+
},
|
|
429
|
+
play: async ({ args, canvasElement, step }) => {
|
|
430
|
+
const canvas = within(canvasElement);
|
|
431
|
+
const body = within(document.body);
|
|
432
|
+
|
|
433
|
+
await step('Focus trigger with keyboard', async () => {
|
|
434
|
+
const trigger = canvas.getByTestId('keyboard-select-trigger');
|
|
435
|
+
trigger.focus();
|
|
436
|
+
await expect(trigger).toHaveFocus();
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
await step('Open dropdown with Enter key', async () => {
|
|
440
|
+
await userEvent.keyboard('{Enter}');
|
|
441
|
+
|
|
442
|
+
const content = await body.findByTestId('keyboard-select-content');
|
|
443
|
+
await expect(content).toBeInTheDocument();
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
await step('Navigate with arrow keys', async () => {
|
|
447
|
+
// Test arrow key navigation
|
|
448
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
449
|
+
await userEvent.keyboard('{ArrowDown}');
|
|
450
|
+
|
|
451
|
+
// Select with Enter
|
|
452
|
+
await userEvent.keyboard('{Enter}');
|
|
453
|
+
|
|
454
|
+
// Should have selected an option
|
|
455
|
+
await expect(args.onValueChange).toHaveBeenCalled();
|
|
456
|
+
});
|
|
457
|
+
},
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
export const MultipleSelectionsTest: Story = {
|
|
461
|
+
tags: ['!dev', '!autodocs'],
|
|
462
|
+
args: {
|
|
463
|
+
items: basicItems,
|
|
464
|
+
placeholder: 'Select an option',
|
|
465
|
+
onValueChange: fn(),
|
|
466
|
+
testId: 'multiple-select',
|
|
467
|
+
},
|
|
468
|
+
play: async ({ args, canvasElement, step }) => {
|
|
469
|
+
const canvas = within(canvasElement);
|
|
470
|
+
const body = within(document.body);
|
|
471
|
+
|
|
472
|
+
await step('Select first option', async () => {
|
|
473
|
+
const trigger = canvas.getByTestId('multiple-select-trigger');
|
|
474
|
+
await userEvent.click(trigger);
|
|
475
|
+
|
|
476
|
+
const option1 = await body.findByTestId('multiple-select-option-option1');
|
|
477
|
+
await userEvent.click(option1);
|
|
478
|
+
|
|
479
|
+
await expect(args.onValueChange).toHaveBeenCalledWith('option1');
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
await step('Change selection to different option', async () => {
|
|
483
|
+
const trigger = canvas.getByTestId('multiple-select-trigger');
|
|
484
|
+
await userEvent.click(trigger);
|
|
485
|
+
|
|
486
|
+
const option3 = await body.findByTestId('multiple-select-option-option3');
|
|
487
|
+
await userEvent.click(option3);
|
|
488
|
+
|
|
489
|
+
await expect(args.onValueChange).toHaveBeenCalledWith('option3');
|
|
490
|
+
|
|
491
|
+
// Verify trigger shows new selection
|
|
492
|
+
await expect(trigger).toHaveTextContent('Option 3');
|
|
493
|
+
});
|
|
494
|
+
},
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
export const PerformanceTest: Story = {
|
|
498
|
+
tags: ['!dev', '!autodocs'],
|
|
499
|
+
args: {
|
|
500
|
+
items: manyItems,
|
|
501
|
+
placeholder: 'Choose a fruit',
|
|
502
|
+
onValueChange: fn(),
|
|
503
|
+
testId: 'performance-select',
|
|
504
|
+
},
|
|
505
|
+
play: async ({ canvasElement, step }) => {
|
|
506
|
+
const canvas = within(canvasElement);
|
|
507
|
+
const body = within(document.body);
|
|
508
|
+
|
|
509
|
+
await step('Measure dropdown open performance', async () => {
|
|
510
|
+
const startTime = performance.now();
|
|
511
|
+
|
|
512
|
+
const trigger = canvas.getByTestId('performance-select-trigger');
|
|
513
|
+
await userEvent.click(trigger);
|
|
514
|
+
|
|
515
|
+
const content = await body.findByTestId('performance-select-content');
|
|
516
|
+
await expect(content).toBeInTheDocument();
|
|
517
|
+
|
|
518
|
+
const endTime = performance.now();
|
|
519
|
+
const renderTime = endTime - startTime;
|
|
520
|
+
|
|
521
|
+
console.log(`CustomSelect dropdown render time: ${renderTime}ms`);
|
|
522
|
+
|
|
523
|
+
// Verify reasonable render time (less than 100ms for 8 items)
|
|
524
|
+
expect(renderTime).toBeLessThan(100);
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
await step('Verify all items rendered', async () => {
|
|
528
|
+
for (const item of manyItems) {
|
|
529
|
+
const option = body.getByTestId(
|
|
530
|
+
`performance-select-option-${item.value}`,
|
|
531
|
+
);
|
|
532
|
+
await expect(option).toBeInTheDocument();
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
},
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
export const AccessibilityTest: Story = {
|
|
539
|
+
tags: ['!dev', '!autodocs'],
|
|
540
|
+
args: {
|
|
541
|
+
items: basicItems,
|
|
542
|
+
placeholder: 'Select an option',
|
|
543
|
+
onValueChange: fn(),
|
|
544
|
+
testId: 'accessibility-select',
|
|
545
|
+
},
|
|
546
|
+
play: async ({ canvasElement, step }) => {
|
|
547
|
+
const canvas = within(canvasElement);
|
|
548
|
+
const body = within(document.body);
|
|
549
|
+
|
|
550
|
+
await step('Verify ARIA attributes', async () => {
|
|
551
|
+
const trigger = canvas.getByTestId('accessibility-select-trigger');
|
|
552
|
+
await expect(trigger).toBeInTheDocument();
|
|
553
|
+
|
|
554
|
+
// Check that it's a button element (no need for explicit role="button")
|
|
555
|
+
await expect(trigger.tagName).toBe('BUTTON');
|
|
556
|
+
|
|
557
|
+
// Check for ARIA attributes
|
|
558
|
+
await expect(trigger).toHaveAttribute('aria-haspopup', 'menu');
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
await step('Verify keyboard accessibility', async () => {
|
|
562
|
+
const trigger = canvas.getByTestId('accessibility-select-trigger');
|
|
563
|
+
|
|
564
|
+
// Test tab navigation
|
|
565
|
+
trigger.focus();
|
|
566
|
+
await expect(trigger).toHaveFocus();
|
|
567
|
+
|
|
568
|
+
// Test space bar to open
|
|
569
|
+
await userEvent.keyboard(' ');
|
|
570
|
+
|
|
571
|
+
const content = await body.findByTestId('accessibility-select-content');
|
|
572
|
+
await expect(content).toBeInTheDocument();
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
await step('Test Escape key to close', async () => {
|
|
576
|
+
await userEvent.keyboard('{Escape}');
|
|
577
|
+
|
|
578
|
+
const content = body.queryByTestId('accessibility-select-content');
|
|
579
|
+
await expect(content).not.toBeInTheDocument();
|
|
580
|
+
});
|
|
581
|
+
},
|
|
582
|
+
};
|