@shopify/shop-minis-react 0.1.4 → 0.1.6

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.
Files changed (125) hide show
  1. package/dist/_virtual/index7.js +2 -3
  2. package/dist/_virtual/index7.js.map +1 -1
  3. package/dist/_virtual/index8.js +3 -2
  4. package/dist/_virtual/index8.js.map +1 -1
  5. package/dist/components/atoms/list.js +110 -48
  6. package/dist/components/atoms/list.js.map +1 -1
  7. package/dist/components/commerce/add-to-cart.js +82 -0
  8. package/dist/components/commerce/add-to-cart.js.map +1 -0
  9. package/dist/components/{atoms → commerce}/favorite-button.js +1 -1
  10. package/dist/components/commerce/favorite-button.js.map +1 -0
  11. package/dist/components/commerce/product-card.js +10 -10
  12. package/dist/components/commerce/product-card.js.map +1 -1
  13. package/dist/components/commerce/product-link.js +6 -6
  14. package/dist/components/commerce/product-link.js.map +1 -1
  15. package/dist/components/commerce/search.js +73 -77
  16. package/dist/components/commerce/search.js.map +1 -1
  17. package/dist/components/ui/accordion.js +1 -1
  18. package/dist/components/ui/alert-dialog.js +1 -1
  19. package/dist/components/ui/avatar.js +1 -1
  20. package/dist/components/ui/checkbox.js +1 -1
  21. package/dist/components/ui/dialog.js +1 -1
  22. package/dist/components/ui/label.js +1 -1
  23. package/dist/components/ui/progress.js +1 -1
  24. package/dist/components/ui/radio-group.js +1 -1
  25. package/dist/components/ui/scroll-area.js +1 -1
  26. package/dist/components/ui/select.js +1 -1
  27. package/dist/components/ui/separator.js +1 -1
  28. package/dist/components/ui/sheet.js +1 -1
  29. package/dist/index.js +276 -274
  30. package/dist/index.js.map +1 -1
  31. package/dist/internal/components/refresh-indicator.js +83 -0
  32. package/dist/internal/components/refresh-indicator.js.map +1 -0
  33. package/dist/internal/usePullToRefresh.js +149 -0
  34. package/dist/internal/usePullToRefresh.js.map +1 -0
  35. package/dist/internal/utils/virtuoso-dom.js +20 -0
  36. package/dist/internal/utils/virtuoso-dom.js.map +1 -0
  37. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-accordion@1.2.11_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19_krqvbhitcyb3vl2jzw3fp35uhu → @radix-ui_react-accordion@1.2.11_@types_react-dom@19.1.6_@types_react@19.1.6__@types_re_c181f188656cfa5f16c2710ccd54e5dd}/node_modules/@radix-ui/react-accordion/dist/index.js +3 -3
  38. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-accordion@1.2.11_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19_krqvbhitcyb3vl2jzw3fp35uhu → @radix-ui_react-accordion@1.2.11_@types_react-dom@19.1.6_@types_react@19.1.6__@types_re_c181f188656cfa5f16c2710ccd54e5dd}/node_modules/@radix-ui/react-accordion/dist/index.js.map +1 -1
  39. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-alert-dialog@1.1.14_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react_5smkpul3xqqoqjowwwfk226yey → @radix-ui_react-alert-dialog@1.1.14_@types_react-dom@19.1.6_@types_react@19.1.6__@types_285ea9ce18742a8c4e84cbcde06e0b25}/node_modules/@radix-ui/react-alert-dialog/dist/index.js +1 -1
  40. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-alert-dialog@1.1.14_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react_5smkpul3xqqoqjowwwfk226yey → @radix-ui_react-alert-dialog@1.1.14_@types_react-dom@19.1.6_@types_react@19.1.6__@types_285ea9ce18742a8c4e84cbcde06e0b25}/node_modules/@radix-ui/react-alert-dialog/dist/index.js.map +1 -1
  41. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-arrow@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1.6__tqbcahbocnte57ax4r75bgnpei → @radix-ui_react-arrow@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@1_37a4d12c56f285a88c8895f81bd600a0}/node_modules/@radix-ui/react-arrow/dist/index.js +1 -1
  42. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-arrow@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1.6__tqbcahbocnte57ax4r75bgnpei → @radix-ui_react-arrow@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@1_37a4d12c56f285a88c8895f81bd600a0}/node_modules/@radix-ui/react-arrow/dist/index.js.map +1 -1
  43. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-avatar@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1._hkz57sehyui4ndfh3rsqwxftli → @radix-ui_react-avatar@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react_06170eb4026a170071caea5f0c82612e}/node_modules/@radix-ui/react-avatar/dist/index.js +1 -1
  44. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-avatar@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1._hkz57sehyui4ndfh3rsqwxftli → @radix-ui_react-avatar@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react_06170eb4026a170071caea5f0c82612e}/node_modules/@radix-ui/react-avatar/dist/index.js.map +1 -1
  45. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-checkbox@1.3.2_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1_wopssf2yyhcdxk6apqq3fxlekq → @radix-ui_react-checkbox@1.3.2_@types_react-dom@19.1.6_@types_react@19.1.6__@types_reac_76c2d9960806d267f7566af463150dec}/node_modules/@radix-ui/react-checkbox/dist/index.js +2 -2
  46. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-checkbox@1.3.2_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1_wopssf2yyhcdxk6apqq3fxlekq → @radix-ui_react-checkbox@1.3.2_@types_react-dom@19.1.6_@types_react@19.1.6__@types_reac_76c2d9960806d267f7566af463150dec}/node_modules/@radix-ui/react-checkbox/dist/index.js.map +1 -1
  47. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-collapsible@1.1.11_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@_4e7bghgww3y6lafncm5x7ie54a → @radix-ui_react-collapsible@1.1.11_@types_react-dom@19.1.6_@types_react@19.1.6__@types__4a84ef457ec365b76d5b35ae363501b4}/node_modules/@radix-ui/react-collapsible/dist/index.js +2 -2
  48. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-collapsible@1.1.11_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@_4e7bghgww3y6lafncm5x7ie54a → @radix-ui_react-collapsible@1.1.11_@types_react-dom@19.1.6_@types_react@19.1.6__@types__4a84ef457ec365b76d5b35ae363501b4}/node_modules/@radix-ui/react-collapsible/dist/index.js.map +1 -1
  49. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-collection@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19_5kif5qsljjcymh5vn5h26ovoye → @radix-ui_react-collection@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_re_773c2f41d00caf3f92b3d7605949da61}/node_modules/@radix-ui/react-collection/dist/index.js.map +1 -1
  50. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-dialog@1.1.14_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1._sjczexpvrqz6fttoobpwnns2oa → @radix-ui_react-dialog@1.1.14_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react_00050fb27f6e4250402df169ba62a563}/node_modules/@radix-ui/react-dialog/dist/index.js +5 -5
  51. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-dialog@1.1.14_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1._sjczexpvrqz6fttoobpwnns2oa → @radix-ui_react-dialog@1.1.14_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react_00050fb27f6e4250402df169ba62a563}/node_modules/@radix-ui/react-dialog/dist/index.js.map +1 -1
  52. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-dismissable-layer@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@types__ipor64qsap4jnr6m7nflv4q5v4 → @radix-ui_react-dismissable-layer@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@_4b09e0704ece360f13e36cbb3765ea47}/node_modules/@radix-ui/react-dismissable-layer/dist/index.js +1 -1
  53. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-dismissable-layer@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@types__ipor64qsap4jnr6m7nflv4q5v4 → @radix-ui_react-dismissable-layer@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@_4b09e0704ece360f13e36cbb3765ea47}/node_modules/@radix-ui/react-dismissable-layer/dist/index.js.map +1 -1
  54. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-focus-scope@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@1_zpdtvgogfsfavk62phevpdv4fu → @radix-ui_react-focus-scope@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_r_b37fcafba5387ffb2fedae9e4476c837}/node_modules/@radix-ui/react-focus-scope/dist/index.js +1 -1
  55. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-focus-scope@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@1_zpdtvgogfsfavk62phevpdv4fu → @radix-ui_react-focus-scope@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_r_b37fcafba5387ffb2fedae9e4476c837}/node_modules/@radix-ui/react-focus-scope/dist/index.js.map +1 -1
  56. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-label@2.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1.6__a5hm3akpfjy2hepxrptadu7t6e → @radix-ui_react-label@2.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@1_85b8c95b65bf0dd4cc21629f4084a5b6}/node_modules/@radix-ui/react-label/dist/index.js +1 -1
  57. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-label@2.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1.6__a5hm3akpfjy2hepxrptadu7t6e → @radix-ui_react-label@2.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@1_85b8c95b65bf0dd4cc21629f4084a5b6}/node_modules/@radix-ui/react-label/dist/index.js.map +1 -1
  58. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-popper@1.2.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1.6_2sktqq4blwmd3t7e5jqffehtuu → @radix-ui_react-popper@1.2.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@_7f041a511b7212d213e8dcc35ea98be2}/node_modules/@radix-ui/react-popper/dist/index.js +2 -2
  59. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-popper@1.2.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1.6_2sktqq4blwmd3t7e5jqffehtuu → @radix-ui_react-popper@1.2.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@_7f041a511b7212d213e8dcc35ea98be2}/node_modules/@radix-ui/react-popper/dist/index.js.map +1 -1
  60. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-portal@1.1.9_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1.6_sr45arufxpp6hzdn2l7kcrtvqe → @radix-ui_react-portal@1.1.9_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@_dbd1c487dbf0f36d89874abfade43936}/node_modules/@radix-ui/react-portal/dist/index.js +1 -1
  61. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-portal@1.1.9_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1.6_sr45arufxpp6hzdn2l7kcrtvqe → @radix-ui_react-portal@1.1.9_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@_dbd1c487dbf0f36d89874abfade43936}/node_modules/@radix-ui/react-portal/dist/index.js.map +1 -1
  62. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-presence@1.1.4_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1_5ga5lr7i6zouk7rhd63vbsmjyu → @radix-ui_react-presence@1.1.4_@types_react-dom@19.1.6_@types_react@19.1.6__@types_reac_14564cac32122309a7cc56096494b6e8}/node_modules/@radix-ui/react-presence/dist/index.js.map +1 -1
  63. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-primitive@2.1.3_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19._5iu4xtybujtep4zwi6jviky6tu → @radix-ui_react-primitive@2.1.3_@types_react-dom@19.1.6_@types_react@19.1.6__@types_rea_ec571b14c8dc7e1c1fa1383d9a1e10bd}/node_modules/@radix-ui/react-primitive/dist/index.js.map +1 -1
  64. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-progress@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1_psrnvm437duefd2y5sh3bqj3sm → @radix-ui_react-progress@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_reac_fa1ba230d1dfc5fe2a0cedd9ff78309e}/node_modules/@radix-ui/react-progress/dist/index.js +1 -1
  65. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-progress@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1_psrnvm437duefd2y5sh3bqj3sm → @radix-ui_react-progress@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_reac_fa1ba230d1dfc5fe2a0cedd9ff78309e}/node_modules/@radix-ui/react-progress/dist/index.js.map +1 -1
  66. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-radio-group@1.3.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@1_b6vd3n6tkje342bk7jtbsrqyfe → @radix-ui_react-radio-group@1.3.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_r_4bdbb04c93e325d7f20e33cc8e004c83}/node_modules/@radix-ui/react-radio-group/dist/index.js +3 -3
  67. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-radio-group@1.3.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@1_b6vd3n6tkje342bk7jtbsrqyfe → @radix-ui_react-radio-group@1.3.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_r_4bdbb04c93e325d7f20e33cc8e004c83}/node_modules/@radix-ui/react-radio-group/dist/index.js.map +1 -1
  68. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-roving-focus@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react_g7ajeb2xgflky4nc3ccraxd5vi → @radix-ui_react-roving-focus@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@types_2d3f19e691372edf0bc25a87278ce401}/node_modules/@radix-ui/react-roving-focus/dist/index.js +2 -2
  69. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-roving-focus@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react_g7ajeb2xgflky4nc3ccraxd5vi → @radix-ui_react-roving-focus@1.1.10_@types_react-dom@19.1.6_@types_react@19.1.6__@types_2d3f19e691372edf0bc25a87278ce401}/node_modules/@radix-ui/react-roving-focus/dist/index.js.map +1 -1
  70. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-scroll-area@1.2.9_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@1_na6tcikkwmgt5sgxl6ezf7zaf4 → @radix-ui_react-scroll-area@1.2.9_@types_react-dom@19.1.6_@types_react@19.1.6__@types_r_b5d13464c21f88022505288dd3198025}/node_modules/@radix-ui/react-scroll-area/dist/index.js +2 -2
  71. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-scroll-area@1.2.9_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@1_na6tcikkwmgt5sgxl6ezf7zaf4 → @radix-ui_react-scroll-area@1.2.9_@types_react-dom@19.1.6_@types_react@19.1.6__@types_r_b5d13464c21f88022505288dd3198025}/node_modules/@radix-ui/react-scroll-area/dist/index.js.map +1 -1
  72. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-select@2.2.5_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1.6_pvbs4vbfxc35gflcf62ix5b3oy → @radix-ui_react-select@2.2.5_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@_8c539485311b2ef067a182d5db805374}/node_modules/@radix-ui/react-select/dist/index.js +7 -7
  73. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-select@2.2.5_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1.6_pvbs4vbfxc35gflcf62ix5b3oy → @radix-ui_react-select@2.2.5_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@_8c539485311b2ef067a182d5db805374}/node_modules/@radix-ui/react-select/dist/index.js.map +1 -1
  74. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-separator@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19._v5c7fe2eicmnfbsit6liht3cja → @radix-ui_react-separator@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_rea_c3003570fa0d6f9943d03ab6b06417ce}/node_modules/@radix-ui/react-separator/dist/index.js +1 -1
  75. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-separator@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19._v5c7fe2eicmnfbsit6liht3cja → @radix-ui_react-separator@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_rea_c3003570fa0d6f9943d03ab6b06417ce}/node_modules/@radix-ui/react-separator/dist/index.js.map +1 -1
  76. package/dist/shop-minis-react/node_modules/.pnpm/@radix-ui_react-use-is-hydrated@0.1.0_@types_react@19.1.6_react@19.1.0/node_modules/@radix-ui/react-use-is-hydrated/dist/index.js +1 -1
  77. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-visually-hidden@1.2.3_@types_react-dom@19.1.6_@types_react@19.1.6__@types_rea_3rnyx4jgemf4vn7spx7uohk4ne → @radix-ui_react-visually-hidden@1.2.3_@types_react-dom@19.1.6_@types_react@19.1.6__@typ_4a5a40fef19214ea28d77d9af27dab61}/node_modules/@radix-ui/react-visually-hidden/dist/index.js +1 -1
  78. package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-visually-hidden@1.2.3_@types_react-dom@19.1.6_@types_react@19.1.6__@types_rea_3rnyx4jgemf4vn7spx7uohk4ne → @radix-ui_react-visually-hidden@1.2.3_@types_react-dom@19.1.6_@types_react@19.1.6__@typ_4a5a40fef19214ea28d77d9af27dab61}/node_modules/@radix-ui/react-visually-hidden/dist/index.js.map +1 -1
  79. package/dist/shop-minis-react/node_modules/.pnpm/color-string@1.9.1/node_modules/color-string/index.js +1 -1
  80. package/dist/shop-minis-react/node_modules/.pnpm/motion@12.17.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/motion/dist/es/framer-motion/dist/es/components/AnimatePresence/PopChild.js +55 -0
  81. package/dist/shop-minis-react/node_modules/.pnpm/motion@12.17.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/motion/dist/es/framer-motion/dist/es/components/AnimatePresence/PopChild.js.map +1 -0
  82. package/dist/shop-minis-react/node_modules/.pnpm/motion@12.17.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/motion/dist/es/framer-motion/dist/es/components/AnimatePresence/PresenceChild.js +35 -0
  83. package/dist/shop-minis-react/node_modules/.pnpm/motion@12.17.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/motion/dist/es/framer-motion/dist/es/components/AnimatePresence/PresenceChild.js.map +1 -0
  84. package/dist/shop-minis-react/node_modules/.pnpm/motion@12.17.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/motion/dist/es/framer-motion/dist/es/components/AnimatePresence/index.js +46 -0
  85. package/dist/shop-minis-react/node_modules/.pnpm/motion@12.17.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/motion/dist/es/framer-motion/dist/es/components/AnimatePresence/index.js.map +1 -0
  86. package/dist/shop-minis-react/node_modules/.pnpm/motion@12.17.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/motion/dist/es/framer-motion/dist/es/components/AnimatePresence/utils.js +13 -0
  87. package/dist/shop-minis-react/node_modules/.pnpm/motion@12.17.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/motion/dist/es/framer-motion/dist/es/components/AnimatePresence/utils.js.map +1 -0
  88. package/dist/shop-minis-react/node_modules/.pnpm/react-virtuoso@4.14.0_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/react-virtuoso/dist/index.js +3132 -0
  89. package/dist/shop-minis-react/node_modules/.pnpm/react-virtuoso@4.14.0_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/react-virtuoso/dist/index.js.map +1 -0
  90. package/dist/shop-minis-react/node_modules/.pnpm/simple-swizzle@0.2.2/node_modules/simple-swizzle/index.js +1 -1
  91. package/dist/shop-minis-react/node_modules/.pnpm/use-sync-external-store@1.5.0_react@19.1.0/node_modules/use-sync-external-store/shim/index.js +1 -1
  92. package/dist/shop-minis-react/node_modules/.pnpm/vaul@1.1.2_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1.6_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/vaul/dist/index.js +1 -1
  93. package/package.json +2 -2
  94. package/src/components/atoms/list.tsx +115 -66
  95. package/src/components/commerce/add-to-cart.test.tsx +73 -0
  96. package/src/components/commerce/add-to-cart.tsx +132 -0
  97. package/src/components/{atoms → commerce}/favorite-button.tsx +1 -1
  98. package/src/components/commerce/product-card.tsx +2 -1
  99. package/src/components/commerce/product-link.tsx +2 -1
  100. package/src/components/commerce/search.tsx +0 -6
  101. package/src/components/index.ts +2 -1
  102. package/src/internal/components/refresh-indicator.tsx +103 -0
  103. package/src/internal/usePullToRefresh.ts +286 -0
  104. package/src/internal/utils/virtuoso-dom.ts +26 -0
  105. package/src/stories/AddToCart.stories.tsx +186 -0
  106. package/src/stories/FavoriteButton.stories.tsx +2 -2
  107. package/src/stories/List.stories.tsx +0 -4
  108. package/src/stories/PullToRefreshList.stories.tsx +122 -0
  109. package/src/styles/animations.css +54 -0
  110. package/src/test-setup.ts +68 -0
  111. package/dist/components/atoms/favorite-button.js.map +0 -1
  112. package/dist/shop-minis-react/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js +0 -8
  113. package/dist/shop-minis-react/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js.map +0 -1
  114. package/dist/shop-minis-react/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/inheritsLoose.js +0 -8
  115. package/dist/shop-minis-react/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/inheritsLoose.js.map +0 -1
  116. package/dist/shop-minis-react/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js +0 -9
  117. package/dist/shop-minis-react/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js.map +0 -1
  118. package/dist/shop-minis-react/node_modules/.pnpm/memoize-one@5.2.1/node_modules/memoize-one/dist/memoize-one.esm.js +0 -28
  119. package/dist/shop-minis-react/node_modules/.pnpm/memoize-one@5.2.1/node_modules/memoize-one/dist/memoize-one.esm.js.map +0 -1
  120. package/dist/shop-minis-react/node_modules/.pnpm/react-window@1.8.11_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/react-window/dist/index.esm.js +0 -375
  121. package/dist/shop-minis-react/node_modules/.pnpm/react-window@1.8.11_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/react-window/dist/index.esm.js.map +0 -1
  122. /package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-collection@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19_5kif5qsljjcymh5vn5h26ovoye → @radix-ui_react-collection@1.1.7_@types_react-dom@19.1.6_@types_react@19.1.6__@types_re_773c2f41d00caf3f92b3d7605949da61}/node_modules/@radix-ui/react-collection/dist/index.js +0 -0
  123. /package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-presence@1.1.4_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19.1_5ga5lr7i6zouk7rhd63vbsmjyu → @radix-ui_react-presence@1.1.4_@types_react-dom@19.1.6_@types_react@19.1.6__@types_reac_14564cac32122309a7cc56096494b6e8}/node_modules/@radix-ui/react-presence/dist/index.js +0 -0
  124. /package/dist/shop-minis-react/node_modules/.pnpm/{@radix-ui_react-primitive@2.1.3_@types_react-dom@19.1.6_@types_react@19.1.6__@types_react@19._5iu4xtybujtep4zwi6jviky6tu → @radix-ui_react-primitive@2.1.3_@types_react-dom@19.1.6_@types_react@19.1.6__@types_rea_ec571b14c8dc7e1c1fa1383d9a1e10bd}/node_modules/@radix-ui/react-primitive/dist/index.js +0 -0
  125. /package/src/components/{atoms → commerce}/favorite-button.test.tsx +0 -0
@@ -1,6 +1,5 @@
1
- import { __require as r } from "../shop-minis-react/node_modules/.pnpm/use-sync-external-store@1.5.0_react@19.1.0/node_modules/use-sync-external-store/shim/index.js";
2
- var i = r();
1
+ var o = { exports: {} };
3
2
  export {
4
- i as s
3
+ o as __module
5
4
  };
6
5
  //# sourceMappingURL=index7.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index7.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
1
+ {"version":3,"file":"index7.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,5 +1,6 @@
1
- var o = { exports: {} };
1
+ import { __require as r } from "../shop-minis-react/node_modules/.pnpm/use-sync-external-store@1.5.0_react@19.1.0/node_modules/use-sync-external-store/shim/index.js";
2
+ var i = r();
2
3
  export {
3
- o as __module
4
+ i as s
4
5
  };
5
6
  //# sourceMappingURL=index8.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index8.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"index8.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -1,58 +1,120 @@
1
- import { jsxs as m, jsx as n } from "react/jsx-runtime";
2
- import { useRef as V, useCallback as f } from "react";
3
- import { VariableSizeList as _ } from "../../shop-minis-react/node_modules/.pnpm/react-window@1.8.11_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/react-window/dist/index.esm.js";
4
- import { cn as j } from "../../lib/utils.js";
1
+ import { jsx as e, Fragment as D, jsxs as g } from "react/jsx-runtime";
2
+ import { useRef as f, useCallback as a, useEffect as w } from "react";
3
+ import { Virtuoso as I } from "../../shop-minis-react/node_modules/.pnpm/react-virtuoso@4.14.0_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/react-virtuoso/dist/index.js";
4
+ import { RefreshIndicator as M } from "../../internal/components/refresh-indicator.js";
5
+ import { usePullToRefresh as U } from "../../internal/usePullToRefresh.js";
6
+ import { findVirtuosoScrollableElement as V } from "../../internal/utils/virtuoso-dom.js";
7
+ import { cn as x } from "../../lib/utils.js";
5
8
  /* empty css */
6
- import { Pagination as C } from "./pagination.js";
7
- const N = _;
8
- function q({
9
- items: t,
10
- height: p,
11
- renderItem: o,
12
- className: v,
13
- showScrollbar: b = !1,
14
- header: i,
15
- headerHeight: c,
16
- itemSizeForRow: a,
17
- fetchMore: l,
18
- overscanCount: g,
19
- ...h
9
+ import { Pagination as k } from "./pagination.js";
10
+ const H = 200, q = 100;
11
+ function W({
12
+ items: L,
13
+ height: N,
14
+ renderItem: p,
15
+ className: _,
16
+ showScrollbar: F = !1,
17
+ header: u,
18
+ fetchMore: r,
19
+ loadingComponent: E,
20
+ isFetchingMore: h,
21
+ onRefresh: n,
22
+ refreshing: m,
23
+ enablePullToRefresh: i = !0,
24
+ ...R
20
25
  }) {
21
- const s = V(null), e = f(() => {
22
- if (s.current) return;
23
- const r = Promise.resolve(l?.()).finally(() => {
24
- s.current === r && (s.current = null);
26
+ const l = f(null), y = f(null), s = f(null), { state: o, bindToElement: v } = U({
27
+ onRefresh: n,
28
+ threshold: H,
29
+ enabled: i && !!n
30
+ }), d = a(() => {
31
+ if (l.current) return;
32
+ const t = Promise.resolve(r?.()).finally(() => {
33
+ l.current === t && (l.current = null);
25
34
  });
26
- s.current = r;
27
- }, [l]), L = f(
28
- ({ index: r, style: u }) => i && r === 0 ? /* @__PURE__ */ m("div", { style: u, children: [
29
- i,
30
- /* @__PURE__ */ n("div", { style: { top: c }, children: o(t[0], 0) })
31
- ] }) : l && r === t.length - 1 ? /* @__PURE__ */ m("div", { style: u, children: [
32
- o(t[r], r),
33
- /* @__PURE__ */ n("div", { style: { bottom: 0 }, children: /* @__PURE__ */ n(C, { fetchMore: e }) })
34
- ] }) : /* @__PURE__ */ n("div", { style: u, children: o(t[r], r) }),
35
- [t, o, i, c, e, l]
36
- ), z = f(
37
- (r) => i && r === 0 ? (c || 0) + a(r) : a(r),
38
- [a, i, c]
39
- ), S = j(b ? void 0 : "no-scrollbars", v);
40
- return /* @__PURE__ */ n(
41
- N,
35
+ l.current = t;
36
+ }, [r]), A = a(
37
+ (t, c) => /* @__PURE__ */ e(D, { children: p(c, t) }),
38
+ [p]
39
+ ), B = a(() => r ? /* @__PURE__ */ e(
40
+ k,
42
41
  {
43
- className: S,
44
- height: p,
45
- direction: "vertical",
46
- width: "100%",
47
- itemCount: t.length,
48
- overscanCount: g,
49
- itemSize: z,
50
- ...h,
51
- children: L
42
+ fetchMore: d,
43
+ loadingComponent: E,
44
+ isFetchingMore: h
45
+ }
46
+ ) : null, [d, r, E, h]), S = x(F ? void 0 : "no-scrollbars", _);
47
+ w(() => {
48
+ if (s.current && i && n) {
49
+ let t;
50
+ const j = setTimeout(() => {
51
+ if (!s.current) return;
52
+ const b = V(
53
+ s.current
54
+ );
55
+ t = v(b);
56
+ }, q);
57
+ return () => {
58
+ clearTimeout(j), t && t();
59
+ };
60
+ }
61
+ }, [v, i, n]);
62
+ const T = a(() => {
63
+ const t = m ? Math.max(o.pullDistance, 140) : o.pullDistance, c = Math.min(
64
+ Math.max(t, 0),
65
+ 140
66
+ );
67
+ return /* @__PURE__ */ g(D, { children: [
68
+ i && n && /* @__PURE__ */ e(
69
+ "div",
70
+ {
71
+ className: "flex items-center justify-center",
72
+ style: {
73
+ height: c,
74
+ overflow: "hidden"
75
+ },
76
+ children: /* @__PURE__ */ e(
77
+ M,
78
+ {
79
+ pullDistance: o.pullDistance,
80
+ threshold: H,
81
+ isRefreshing: m ?? !1,
82
+ canRefresh: o.canRefresh,
83
+ className: "relative top-0 inset-x-auto"
84
+ }
85
+ )
86
+ }
87
+ ),
88
+ u && /* @__PURE__ */ e("div", { children: u })
89
+ ] });
90
+ }, [u, i, n, o, m]);
91
+ return /* @__PURE__ */ e(
92
+ "div",
93
+ {
94
+ ref: s,
95
+ className: x("relative transition-all duration-200", S),
96
+ style: {
97
+ height: N
98
+ },
99
+ children: /* @__PURE__ */ e(
100
+ I,
101
+ {
102
+ ref: y,
103
+ className: "h-full w-full",
104
+ data: L,
105
+ itemContent: A,
106
+ components: {
107
+ Header: T,
108
+ Footer: B
109
+ },
110
+ endReached: r ? d : void 0,
111
+ ...R
112
+ }
113
+ )
52
114
  }
53
115
  );
54
116
  }
55
117
  export {
56
- q as List
118
+ W as List
57
119
  };
58
120
  //# sourceMappingURL=list.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sources":["../../../src/components/atoms/list.tsx"],"sourcesContent":["import {ComponentType, useCallback, useRef} from 'react'\n\nimport {\n VariableSizeList as _VariableSizeList,\n VariableSizeListProps,\n} from 'react-window'\n\nimport {cn} from '../../lib/utils'\nimport '../../styles/utilities.css'\n\nimport {Pagination} from './pagination'\n\nconst VariableSizeList =\n _VariableSizeList as unknown as ComponentType<VariableSizeListProps>\n\ninterface Props<T = any>\n extends Omit<\n VariableSizeListProps<T>,\n 'children' | 'itemCount' | 'width' | 'itemSize' | 'direction'\n > {\n items: T[]\n renderItem: (item: T, index: number) => React.ReactNode\n itemSizeForRow: (index: number) => number\n showScrollbar?: boolean\n header?: React.ReactNode\n headerHeight?: number\n fetchMore?: () => Promise<void>\n}\n\nexport function List<T = any>({\n items,\n height,\n renderItem,\n className,\n showScrollbar = false,\n header,\n headerHeight,\n itemSizeForRow,\n fetchMore,\n overscanCount,\n ...listProps\n}: Props<T>) {\n const inFlightFetchMoreRef = useRef<Promise<void> | null>(null)\n\n // This is workaround to prevent multiple calls to fetchMore\n // react-window re-renders the rows while scrolling,\n // and the TrackingPixel could be triggered multiple times\n\n const _fetchMore = useCallback(() => {\n // Dedupe concurrent calls by returning the same in-flight promise\n if (inFlightFetchMoreRef.current) return\n\n const current = Promise.resolve(fetchMore?.()).finally(() => {\n // Only clear if this is still the most recent promise\n if (inFlightFetchMoreRef.current === current) {\n inFlightFetchMoreRef.current = null\n }\n })\n\n inFlightFetchMoreRef.current = current\n }, [fetchMore])\n\n const rowRenderer = useCallback(\n ({index, style}: {index: number; style: React.CSSProperties}) => {\n // prepend the header to the first row if it exists\n if (header && index === 0) {\n return (\n <div style={style}>\n {header}\n <div style={{top: headerHeight}}>{renderItem(items[0], 0)}</div>\n </div>\n )\n }\n\n // append the pagination spinner to the last row if fetchMore exists\n if (fetchMore && index === items.length - 1) {\n return (\n <div style={style}>\n {renderItem(items[index], index)}\n <div style={{bottom: 0}}>\n <Pagination fetchMore={_fetchMore} />\n </div>\n </div>\n )\n }\n\n return <div style={style}>{renderItem(items[index], index)}</div>\n },\n [items, renderItem, header, headerHeight, _fetchMore, fetchMore]\n )\n\n const getItemSize = useCallback(\n (index: number) => {\n // include the header height in the first row height\n if (header && index === 0) {\n const _headerHeight = headerHeight || 0\n return _headerHeight + itemSizeForRow(index)\n }\n\n return itemSizeForRow(index)\n },\n [itemSizeForRow, header, headerHeight]\n )\n\n const classNames = cn(showScrollbar ? undefined : 'no-scrollbars', className)\n\n return (\n <VariableSizeList\n className={classNames}\n height={height}\n direction=\"vertical\"\n width=\"100%\"\n itemCount={items.length}\n overscanCount={overscanCount}\n itemSize={getItemSize}\n {...listProps}\n >\n {rowRenderer}\n </VariableSizeList>\n )\n}\n"],"names":["VariableSizeList","_VariableSizeList","List","items","height","renderItem","className","showScrollbar","header","headerHeight","itemSizeForRow","fetchMore","overscanCount","listProps","inFlightFetchMoreRef","useRef","_fetchMore","useCallback","current","rowRenderer","index","style","jsxs","jsx","Pagination","getItemSize","classNames","cn"],"mappings":";;;;;;AAYA,MAAMA,IACJC;AAgBK,SAASC,EAAc;AAAA,EAC5B,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AAAA,EACA,eAAAC,IAAgB;AAAA,EAChB,QAAAC;AAAA,EACA,cAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,GAAGC;AACL,GAAa;AACL,QAAAC,IAAuBC,EAA6B,IAAI,GAMxDC,IAAaC,EAAY,MAAM;AAEnC,QAAIH,EAAqB,QAAS;AAElC,UAAMI,IAAU,QAAQ,QAAQP,IAAa,CAAA,EAAE,QAAQ,MAAM;AAEvD,MAAAG,EAAqB,YAAYI,MACnCJ,EAAqB,UAAU;AAAA,IACjC,CACD;AAED,IAAAA,EAAqB,UAAUI;AAAA,EAAA,GAC9B,CAACP,CAAS,CAAC,GAERQ,IAAcF;AAAA,IAClB,CAAC,EAAC,OAAAG,GAAO,OAAAC,QAEHb,KAAUY,MAAU,IAEpB,gBAAAE,EAAC,SAAI,OAAAD,GACF,UAAA;AAAA,MAAAb;AAAA,MACA,gBAAAe,EAAA,OAAA,EAAI,OAAO,EAAC,KAAKd,EAAA,GAAgB,UAAAJ,EAAWF,EAAM,CAAC,GAAG,CAAC,EAAE,CAAA;AAAA,IAAA,GAC5D,IAKAQ,KAAaS,MAAUjB,EAAM,SAAS,IAEtC,gBAAAmB,EAAC,SAAI,OAAAD,GACF,UAAA;AAAA,MAAWhB,EAAAF,EAAMiB,CAAK,GAAGA,CAAK;AAAA,MAC/B,gBAAAG,EAAC,OAAI,EAAA,OAAO,EAAC,QAAQ,EAAC,GACpB,UAAC,gBAAAA,EAAAC,GAAA,EAAW,WAAWR,EAAY,CAAA,EACrC,CAAA;AAAA,IAAA,GACF,IAIG,gBAAAO,EAAC,SAAI,OAAAF,GAAe,UAAAhB,EAAWF,EAAMiB,CAAK,GAAGA,CAAK,GAAE;AAAA,IAE7D,CAACjB,GAAOE,GAAYG,GAAQC,GAAcO,GAAYL,CAAS;AAAA,EACjE,GAEMc,IAAcR;AAAA,IAClB,CAACG,MAEKZ,KAAUY,MAAU,KACAX,KAAgB,KACfC,EAAeU,CAAK,IAGtCV,EAAeU,CAAK;AAAA,IAE7B,CAACV,GAAgBF,GAAQC,CAAY;AAAA,EACvC,GAEMiB,IAAaC,EAAGpB,IAAgB,SAAY,iBAAiBD,CAAS;AAG1E,SAAA,gBAAAiB;AAAA,IAACvB;AAAA,IAAA;AAAA,MACC,WAAW0B;AAAA,MACX,QAAAtB;AAAA,MACA,WAAU;AAAA,MACV,OAAM;AAAA,MACN,WAAWD,EAAM;AAAA,MACjB,eAAAS;AAAA,MACA,UAAUa;AAAA,MACT,GAAGZ;AAAA,MAEH,UAAAM;AAAA,IAAA;AAAA,EACH;AAEJ;"}
1
+ {"version":3,"file":"list.js","sources":["../../../src/components/atoms/list.tsx"],"sourcesContent":["import {useCallback, useEffect, useRef} from 'react'\n\nimport {Virtuoso, VirtuosoProps} from 'react-virtuoso'\n\nimport {RefreshIndicator} from '../../internal/components/refresh-indicator'\nimport {usePullToRefresh} from '../../internal/usePullToRefresh'\nimport {findVirtuosoScrollableElement} from '../../internal/utils/virtuoso-dom'\nimport {cn} from '../../lib/utils'\nimport '../../styles/utilities.css'\n\nimport {Pagination} from './pagination'\n\nconst DEFAULT_REFRESH_PULL_THRESHOLD = 200\nconst ELEMENT_BIND_DELAY = 100\n\ninterface Props<T = any>\n extends Omit<\n VirtuosoProps<T, unknown>,\n 'data' | 'itemContent' | 'endReached'\n > {\n items: T[]\n renderItem: (item: T, index: number) => React.ReactNode\n showScrollbar?: boolean\n header?: React.ReactNode\n fetchMore?: () => Promise<void>\n loadingComponent?: React.ReactNode\n isFetchingMore?: boolean\n onRefresh?: () => Promise<void>\n refreshing?: boolean\n enablePullToRefresh?: boolean\n}\n\nexport function List<T = any>({\n items,\n height,\n renderItem,\n className,\n showScrollbar = false,\n header,\n fetchMore,\n loadingComponent,\n isFetchingMore,\n onRefresh,\n refreshing,\n enablePullToRefresh = true,\n ...virtuosoProps\n}: Props<T>) {\n const inFlightFetchMoreRef = useRef<Promise<void> | null>(null)\n const virtuosoRef = useRef<any>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n const {state: pullToRefreshState, bindToElement} = usePullToRefresh({\n onRefresh,\n threshold: DEFAULT_REFRESH_PULL_THRESHOLD,\n enabled: enablePullToRefresh && Boolean(onRefresh),\n })\n\n const _fetchMore = useCallback(() => {\n // Dedupe concurrent calls by returning the same in-flight promise\n if (inFlightFetchMoreRef.current) return\n\n const current = Promise.resolve(fetchMore?.()).finally(() => {\n // Only clear if this is still the most recent promise\n if (inFlightFetchMoreRef.current === current) {\n inFlightFetchMoreRef.current = null\n }\n })\n\n inFlightFetchMoreRef.current = current\n }, [fetchMore])\n\n const itemContent = useCallback(\n (index: number, item: T) => <>{renderItem(item, index)}</>,\n [renderItem]\n )\n\n const Footer = useCallback(() => {\n if (!fetchMore) return null\n\n return (\n <Pagination\n fetchMore={_fetchMore}\n loadingComponent={loadingComponent}\n isFetchingMore={isFetchingMore}\n />\n )\n }, [_fetchMore, fetchMore, loadingComponent, isFetchingMore])\n\n const classNames = cn(showScrollbar ? undefined : 'no-scrollbars', className)\n\n useEffect(() => {\n if (containerRef.current && enablePullToRefresh && onRefresh) {\n let cleanup: (() => void) | undefined\n\n const findAndBind = () => {\n if (!containerRef.current) return\n\n const scrollableElement = findVirtuosoScrollableElement(\n containerRef.current\n )\n cleanup = bindToElement(scrollableElement)\n }\n\n const timeoutId = setTimeout(findAndBind, ELEMENT_BIND_DELAY)\n\n return () => {\n clearTimeout(timeoutId)\n if (cleanup) cleanup()\n }\n }\n return undefined\n }, [bindToElement, enablePullToRefresh, onRefresh])\n\n const EnhancedHeader = useCallback(() => {\n const effectivePullDistance = refreshing\n ? Math.max(pullToRefreshState.pullDistance, 140)\n : pullToRefreshState.pullDistance\n\n const refreshHeaderHeight = Math.min(\n Math.max(effectivePullDistance, 0),\n 140\n )\n\n return (\n <>\n {enablePullToRefresh && onRefresh && (\n <div\n className=\"flex items-center justify-center\"\n style={{\n height: refreshHeaderHeight,\n overflow: 'hidden',\n }}\n >\n <RefreshIndicator\n pullDistance={pullToRefreshState.pullDistance}\n threshold={DEFAULT_REFRESH_PULL_THRESHOLD}\n isRefreshing={refreshing ?? false}\n canRefresh={pullToRefreshState.canRefresh}\n className=\"relative top-0 inset-x-auto\"\n />\n </div>\n )}\n {header && <div>{header}</div>}\n </>\n )\n }, [header, enablePullToRefresh, onRefresh, pullToRefreshState, refreshing])\n\n return (\n <div\n ref={containerRef}\n className={cn('relative transition-all duration-200', classNames)}\n style={{\n height,\n }}\n >\n <Virtuoso\n ref={virtuosoRef}\n className=\"h-full w-full\"\n data={items}\n itemContent={itemContent}\n components={{\n Header: EnhancedHeader,\n Footer,\n }}\n endReached={fetchMore ? _fetchMore : undefined}\n {...virtuosoProps}\n />\n </div>\n )\n}\n"],"names":["DEFAULT_REFRESH_PULL_THRESHOLD","ELEMENT_BIND_DELAY","List","items","height","renderItem","className","showScrollbar","header","fetchMore","loadingComponent","isFetchingMore","onRefresh","refreshing","enablePullToRefresh","virtuosoProps","inFlightFetchMoreRef","useRef","virtuosoRef","containerRef","pullToRefreshState","bindToElement","usePullToRefresh","_fetchMore","useCallback","current","itemContent","index","item","Footer","jsx","Pagination","classNames","cn","useEffect","cleanup","timeoutId","scrollableElement","findVirtuosoScrollableElement","EnhancedHeader","effectivePullDistance","refreshHeaderHeight","jsxs","Fragment","RefreshIndicator","Virtuoso"],"mappings":";;;;;;;;;AAYA,MAAMA,IAAiC,KACjCC,IAAqB;AAmBpB,SAASC,EAAc;AAAA,EAC5B,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AAAA,EACA,eAAAC,IAAgB;AAAA,EAChB,QAAAC;AAAA,EACA,WAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,EACA,qBAAAC,IAAsB;AAAA,EACtB,GAAGC;AACL,GAAa;AACL,QAAAC,IAAuBC,EAA6B,IAAI,GACxDC,IAAcD,EAAY,IAAI,GAC9BE,IAAeF,EAAuB,IAAI,GAE1C,EAAC,OAAOG,GAAoB,eAAAC,EAAA,IAAiBC,EAAiB;AAAA,IAClE,WAAAV;AAAA,IACA,WAAWZ;AAAA,IACX,SAASc,KAAuB,EAAQF;AAAA,EAAS,CAClD,GAEKW,IAAaC,EAAY,MAAM;AAEnC,QAAIR,EAAqB,QAAS;AAElC,UAAMS,IAAU,QAAQ,QAAQhB,IAAa,CAAA,EAAE,QAAQ,MAAM;AAEvD,MAAAO,EAAqB,YAAYS,MACnCT,EAAqB,UAAU;AAAA,IACjC,CACD;AAED,IAAAA,EAAqB,UAAUS;AAAA,EAAA,GAC9B,CAAChB,CAAS,CAAC,GAERiB,IAAcF;AAAA,IAClB,CAACG,GAAeC,6BAAe,UAAWvB,EAAAuB,GAAMD,CAAK,GAAE;AAAA,IACvD,CAACtB,CAAU;AAAA,EACb,GAEMwB,IAASL,EAAY,MACpBf,IAGH,gBAAAqB;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,WAAWR;AAAA,MACX,kBAAAb;AAAA,MACA,gBAAAC;AAAA,IAAA;AAAA,EACF,IAPqB,MAStB,CAACY,GAAYd,GAAWC,GAAkBC,CAAc,CAAC,GAEtDqB,IAAaC,EAAG1B,IAAgB,SAAY,iBAAiBD,CAAS;AAE5E,EAAA4B,EAAU,MAAM;AACV,QAAAf,EAAa,WAAWL,KAAuBF,GAAW;AACxD,UAAAuB;AAWE,YAAAC,IAAY,WATE,MAAM;AACpB,YAAA,CAACjB,EAAa,QAAS;AAE3B,cAAMkB,IAAoBC;AAAA,UACxBnB,EAAa;AAAA,QACf;AACA,QAAAgB,IAAUd,EAAcgB,CAAiB;AAAA,MAC3C,GAE0CpC,CAAkB;AAE5D,aAAO,MAAM;AACX,qBAAamC,CAAS,GAClBD,KAAiBA,EAAA;AAAA,MACvB;AAAA,IAAA;AAAA,EAGD,GAAA,CAACd,GAAeP,GAAqBF,CAAS,CAAC;AAE5C,QAAA2B,IAAiBf,EAAY,MAAM;AACjC,UAAAgB,IAAwB3B,IAC1B,KAAK,IAAIO,EAAmB,cAAc,GAAG,IAC7CA,EAAmB,cAEjBqB,IAAsB,KAAK;AAAA,MAC/B,KAAK,IAAID,GAAuB,CAAC;AAAA,MACjC;AAAA,IACF;AAEA,WAEK,gBAAAE,EAAAC,GAAA,EAAA,UAAA;AAAA,MAAA7B,KAAuBF,KACtB,gBAAAkB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO;AAAA,YACL,QAAQW;AAAA,YACR,UAAU;AAAA,UACZ;AAAA,UAEA,UAAA,gBAAAX;AAAA,YAACc;AAAA,YAAA;AAAA,cACC,cAAcxB,EAAmB;AAAA,cACjC,WAAWpB;AAAA,cACX,cAAca,KAAc;AAAA,cAC5B,YAAYO,EAAmB;AAAA,cAC/B,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACZ;AAAA,MACF;AAAA,MAEDZ,KAAW,gBAAAsB,EAAA,OAAA,EAAK,UAAOtB,EAAA,CAAA;AAAA,IAAA,GAC1B;AAAA,EAAA,GAED,CAACA,GAAQM,GAAqBF,GAAWQ,GAAoBP,CAAU,CAAC;AAGzE,SAAA,gBAAAiB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKX;AAAA,MACL,WAAWc,EAAG,wCAAwCD,CAAU;AAAA,MAChE,OAAO;AAAA,QACL,QAAA5B;AAAA,MACF;AAAA,MAEA,UAAA,gBAAA0B;AAAA,QAACe;AAAAA,QAAA;AAAA,UACC,KAAK3B;AAAA,UACL,WAAU;AAAA,UACV,MAAMf;AAAA,UACN,aAAAuB;AAAA,UACA,YAAY;AAAA,YACV,QAAQa;AAAA,YACR,QAAAV;AAAA,UACF;AAAA,UACA,YAAYpB,IAAYc,IAAa;AAAA,UACpC,GAAGR;AAAA,QAAA;AAAA,MAAA;AAAA,IACN;AAAA,EACF;AAEJ;"}
@@ -0,0 +1,82 @@
1
+ import { jsx as r, jsxs as A } from "react/jsx-runtime";
2
+ import * as m from "react";
3
+ import { useState as T, useCallback as v } from "react";
4
+ import { cn as f } from "../../lib/utils.js";
5
+ import { Button as x } from "../atoms/button.js";
6
+ import { useShopCartActions as C } from "../../hooks/shop/useShopCartActions.js";
7
+ import { useErrorToast as y } from "../../hooks/util/useErrorToast.js";
8
+ import { AnimatePresence as N } from "../../shop-minis-react/node_modules/.pnpm/motion@12.17.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/motion/dist/es/framer-motion/dist/es/components/AnimatePresence/index.js";
9
+ import { motion as k } from "../../shop-minis-react/node_modules/.pnpm/motion@12.17.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/motion/dist/es/framer-motion/dist/es/render/components/motion/proxy.js";
10
+ import w from "../../shop-minis-react/node_modules/.pnpm/lucide-react@0.513.0_react@19.1.0/node_modules/lucide-react/dist/esm/icons/check.js";
11
+ function P({
12
+ disabled: o = !1,
13
+ className: u,
14
+ size: d = "default",
15
+ productId: a,
16
+ productVariantId: i,
17
+ discountCodes: n
18
+ }) {
19
+ const { addToCart: c } = C(), [t, s] = T(!1), e = m.useRef(void 0), { showErrorToast: l } = y(), h = v(async () => {
20
+ if (!(t || o))
21
+ try {
22
+ a && i && c({
23
+ productId: a,
24
+ productVariantId: i,
25
+ quantity: 1,
26
+ discountCodes: n
27
+ }).then(() => {
28
+ }).catch(() => {
29
+ l({ message: "Failed to add to cart" });
30
+ }), s(!0), e.current && clearTimeout(e.current), e.current = window.setTimeout(() => {
31
+ s(!1);
32
+ }, 2e3);
33
+ } catch (p) {
34
+ s(!1), console.error("Failed to add to cart:", p);
35
+ }
36
+ }, [
37
+ t,
38
+ o,
39
+ c,
40
+ a,
41
+ i,
42
+ n,
43
+ l
44
+ ]);
45
+ return m.useEffect(() => () => {
46
+ e.current && clearTimeout(e.current);
47
+ }, []), /* @__PURE__ */ r(
48
+ x,
49
+ {
50
+ onClick: h,
51
+ disabled: o,
52
+ className: f(
53
+ "relative overflow-hidden transition-all duration-300",
54
+ u
55
+ ),
56
+ size: d,
57
+ children: /* @__PURE__ */ A("div", { className: "relative flex items-center justify-center", children: [
58
+ /* @__PURE__ */ r(N, { children: t && /* @__PURE__ */ r(
59
+ k.div,
60
+ {
61
+ initial: { scale: 0, rotate: -180 },
62
+ animate: { scale: 1, rotate: 0 },
63
+ exit: { scale: 0, rotate: 180 },
64
+ transition: {
65
+ duration: 0.4,
66
+ ease: [0.175, 0.885, 0.32, 1.275]
67
+ // bounce effect
68
+ },
69
+ className: "absolute left-0",
70
+ style: { x: -8 },
71
+ children: /* @__PURE__ */ r(w, { className: "size-4" })
72
+ }
73
+ ) }),
74
+ /* @__PURE__ */ r("span", { className: f(t && "pl-5", "transition-all duration-300"), children: t ? "Added to cart" : "Add to cart" })
75
+ ] })
76
+ }
77
+ );
78
+ }
79
+ export {
80
+ P as AddToCartButton
81
+ };
82
+ //# sourceMappingURL=add-to-cart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-to-cart.js","sources":["../../../src/components/commerce/add-to-cart.tsx"],"sourcesContent":["import * as React from 'react'\nimport {useState, useCallback} from 'react'\n\nimport {CheckIcon} from 'lucide-react'\nimport {motion, AnimatePresence} from 'motion/react'\n\nimport {useErrorToast, useShopCartActions} from '../../hooks'\nimport {cn} from '../../lib/utils'\nimport {Button} from '../atoms/button'\n\ninterface AddToCartButtonProps {\n disabled?: boolean\n className?: string\n size?: 'default' | 'sm' | 'lg'\n /**\n * The discount codes to apply to the cart.\n */\n discountCodes?: string[]\n /**\n * The GID of the product. E.g. `gid://shopify/Product/123`.\n */\n productId: string\n /**\n * The GID of the product variant. E.g. `gid://shopify/ProductVariant/456`.\n */\n productVariantId: string\n}\n\nexport function AddToCartButton({\n disabled = false,\n className,\n size = 'default',\n productId,\n productVariantId,\n discountCodes,\n}: AddToCartButtonProps) {\n const {addToCart} = useShopCartActions()\n const [isAdded, setIsAdded] = useState(false)\n const timeoutRef = React.useRef<number | undefined>(undefined)\n\n const {showErrorToast} = useErrorToast()\n\n const handleClick = useCallback(async () => {\n if (isAdded || disabled) return\n\n try {\n // Call the callback if provided\n if (productId && productVariantId) {\n // Optimistic update with error toast\n addToCart({\n productId,\n productVariantId,\n quantity: 1,\n discountCodes,\n })\n .then(() => {})\n .catch(() => {\n showErrorToast({message: 'Failed to add to cart'})\n })\n }\n\n // Show success state\n setIsAdded(true)\n\n // Clear any existing timeout\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current)\n }\n\n // Reset to initial state after delay\n timeoutRef.current = window.setTimeout(() => {\n setIsAdded(false)\n }, 2000)\n } catch (error) {\n // Handle error - reset to initial state\n setIsAdded(false)\n console.error('Failed to add to cart:', error)\n }\n }, [\n isAdded,\n disabled,\n addToCart,\n productId,\n productVariantId,\n discountCodes,\n showErrorToast,\n ])\n\n // Cleanup timeout on unmount\n React.useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current)\n }\n }\n }, [])\n\n return (\n <Button\n onClick={handleClick}\n disabled={disabled}\n className={cn(\n 'relative overflow-hidden transition-all duration-300',\n className\n )}\n size={size}\n >\n <div className=\"relative flex items-center justify-center\">\n <AnimatePresence>\n {isAdded && (\n <motion.div\n initial={{scale: 0, rotate: -180}}\n animate={{scale: 1, rotate: 0}}\n exit={{scale: 0, rotate: 180}}\n transition={{\n duration: 0.4,\n ease: [0.175, 0.885, 0.32, 1.275], // bounce effect\n }}\n className=\"absolute left-0\"\n style={{x: -8}}\n >\n <CheckIcon className=\"size-4\" />\n </motion.div>\n )}\n </AnimatePresence>\n <span className={cn(isAdded && 'pl-5', 'transition-all duration-300')}>\n {isAdded ? 'Added to cart' : 'Add to cart'}\n </span>\n </div>\n </Button>\n )\n}\n"],"names":["AddToCartButton","disabled","className","size","productId","productVariantId","discountCodes","addToCart","useShopCartActions","isAdded","setIsAdded","useState","timeoutRef","React","showErrorToast","useErrorToast","handleClick","useCallback","error","jsx","Button","cn","jsxs","AnimatePresence","motion","CheckIcon"],"mappings":";;;;;;;;;;AA4BO,SAASA,EAAgB;AAAA,EAC9B,UAAAC,IAAW;AAAA,EACX,WAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,WAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,eAAAC;AACF,GAAyB;AACjB,QAAA,EAAC,WAAAC,EAAS,IAAIC,EAAmB,GACjC,CAACC,GAASC,CAAU,IAAIC,EAAS,EAAK,GACtCC,IAAaC,EAAM,OAA2B,MAAS,GAEvD,EAAC,gBAAAC,EAAc,IAAIC,EAAc,GAEjCC,IAAcC,EAAY,YAAY;AAC1C,QAAI,EAAAR,KAAWR;AAEX,UAAA;AAEF,QAAIG,KAAaC,KAELE,EAAA;AAAA,UACR,WAAAH;AAAA,UACA,kBAAAC;AAAA,UACA,UAAU;AAAA,UACV,eAAAC;AAAA,QAAA,CACD,EACE,KAAK,MAAM;AAAA,QAAA,CAAE,EACb,MAAM,MAAM;AACI,UAAAQ,EAAA,EAAC,SAAS,yBAAwB;AAAA,QAAA,CAClD,GAILJ,EAAW,EAAI,GAGXE,EAAW,WACb,aAAaA,EAAW,OAAO,GAItBA,EAAA,UAAU,OAAO,WAAW,MAAM;AAC3C,UAAAF,EAAW,EAAK;AAAA,WACf,GAAI;AAAA,eACAQ,GAAO;AAEd,QAAAR,EAAW,EAAK,GACR,QAAA,MAAM,0BAA0BQ,CAAK;AAAA,MAAA;AAAA,EAC/C,GACC;AAAA,IACDT;AAAA,IACAR;AAAA,IACAM;AAAA,IACAH;AAAA,IACAC;AAAA,IACAC;AAAA,IACAQ;AAAA,EAAA,CACD;AAGD,SAAAD,EAAM,UAAU,MACP,MAAM;AACX,IAAID,EAAW,WACb,aAAaA,EAAW,OAAO;AAAA,EAEnC,GACC,EAAE,GAGH,gBAAAO;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,SAASJ;AAAA,MACT,UAAAf;AAAA,MACA,WAAWoB;AAAA,QACT;AAAA,QACAnB;AAAA,MACF;AAAA,MACA,MAAAC;AAAA,MAEA,UAAA,gBAAAmB,EAAC,OAAI,EAAA,WAAU,6CACb,UAAA;AAAA,QAAA,gBAAAH,EAACI,KACE,UACCd,KAAA,gBAAAU;AAAA,UAACK,EAAO;AAAA,UAAP;AAAA,YACC,SAAS,EAAC,OAAO,GAAG,QAAQ,KAAI;AAAA,YAChC,SAAS,EAAC,OAAO,GAAG,QAAQ,EAAC;AAAA,YAC7B,MAAM,EAAC,OAAO,GAAG,QAAQ,IAAG;AAAA,YAC5B,YAAY;AAAA,cACV,UAAU;AAAA,cACV,MAAM,CAAC,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,YAClC;AAAA,YACA,WAAU;AAAA,YACV,OAAO,EAAC,GAAG,GAAE;AAAA,YAEb,UAAA,gBAAAL,EAACM,GAAU,EAAA,WAAU,SAAS,CAAA;AAAA,UAAA;AAAA,QAAA,GAGpC;AAAA,QACA,gBAAAN,EAAC,QAAK,EAAA,WAAWE,EAAGZ,KAAW,QAAQ,6BAA6B,GACjE,UAAUA,IAAA,kBAAkB,cAC/B,CAAA;AAAA,MAAA,EACF,CAAA;AAAA,IAAA;AAAA,EACF;AAEJ;"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as r } from "react/jsx-runtime";
2
- import { IconButton as n } from "./icon-button.js";
2
+ import { IconButton as n } from "../atoms/icon-button.js";
3
3
  import m from "../../shop-minis-react/node_modules/.pnpm/lucide-react@0.513.0_react@19.1.0/node_modules/lucide-react/dist/esm/icons/heart.js";
4
4
  function e({
5
5
  onClick: t,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"favorite-button.js","sources":["../../../src/components/commerce/favorite-button.tsx"],"sourcesContent":["import {Heart} from 'lucide-react'\n\nimport {IconButton} from '../atoms/icon-button'\n\nexport function FavoriteButton({\n onClick,\n filled = false,\n}: {\n onClick?: () => void\n filled?: boolean\n}) {\n return (\n <IconButton\n Icon={Heart}\n filled={filled}\n onClick={onClick}\n buttonStyles={\n filled ? 'bg-primary' : 'bg-button-overlay/30 backdrop-blur-sm'\n }\n />\n )\n}\n"],"names":["FavoriteButton","onClick","filled","jsx","IconButton","Heart"],"mappings":";;;AAIO,SAASA,EAAe;AAAA,EAC7B,SAAAC;AAAA,EACA,QAAAC,IAAS;AACX,GAGG;AAEC,SAAA,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,MAAMC;AAAA,MACN,QAAAH;AAAA,MACA,SAAAD;AAAA,MACA,cACEC,IAAS,eAAe;AAAA,IAAA;AAAA,EAE5B;AAEJ;"}
@@ -5,11 +5,11 @@ import { useShopNavigation as V } from "../../hooks/navigation/useShopNavigation
5
5
  import { useSavedProductsActions as j } from "../../hooks/user/useSavedProductsActions.js";
6
6
  import { formatMoney as z } from "../../lib/formatMoney.js";
7
7
  import { cn as s } from "../../lib/utils.js";
8
- import { FavoriteButton as B } from "../atoms/favorite-button.js";
9
- import { Image as T } from "../atoms/image.js";
10
- import { ProductVariantPrice as E } from "../atoms/product-variant-price.js";
11
- import { Touchable as O } from "../atoms/touchable.js";
12
- import { Badge as S } from "../ui/badge.js";
8
+ import { Image as B } from "../atoms/image.js";
9
+ import { ProductVariantPrice as T } from "../atoms/product-variant-price.js";
10
+ import { Touchable as E } from "../atoms/touchable.js";
11
+ import { Badge as O } from "../ui/badge.js";
12
+ import { FavoriteButton as S } from "./favorite-button.js";
13
13
  const I = N.createContext(void 0);
14
14
  function u() {
15
15
  const t = k(I);
@@ -34,7 +34,7 @@ function L({
34
34
  }
35
35
  );
36
36
  return r && a ? /* @__PURE__ */ o(
37
- O,
37
+ E,
38
38
  {
39
39
  onClick: a,
40
40
  whileTap: { opacity: 0.7 },
@@ -69,7 +69,7 @@ function M({
69
69
  function R({ className: t, ...e }) {
70
70
  const { product: r, selectedProductVariant: a } = u(), n = a?.image || r.featuredImage, i = n?.url, d = n?.altText || r.title, c = r.featuredImage?.thumbhash, p = C(
71
71
  (l) => c ? /* @__PURE__ */ o(
72
- T,
72
+ B,
73
73
  {
74
74
  "data-slot": "product-card-image",
75
75
  src: l,
@@ -109,7 +109,7 @@ function b({
109
109
  e === "top-left" ? "top-3 left-3" : "bottom-2 left-2"
110
110
  ),
111
111
  children: /* @__PURE__ */ o(
112
- S,
112
+ O,
113
113
  {
114
114
  variant: r ?? d ?? "none",
115
115
  className: s(
@@ -129,7 +129,7 @@ function q({
129
129
  ...e
130
130
  }) {
131
131
  const { isFavorited: r, onFavoriteToggle: a } = u();
132
- return /* @__PURE__ */ o("div", { className: s("absolute bottom-3 right-3 z-10", t), ...e, children: /* @__PURE__ */ o(B, { onClick: a, filled: r }) });
132
+ return /* @__PURE__ */ o("div", { className: s("absolute bottom-3 right-3 z-10", t), ...e, children: /* @__PURE__ */ o(S, { onClick: a, filled: r }) });
133
133
  }
134
134
  function D({ className: t, ...e }) {
135
135
  const { variant: r } = u();
@@ -165,7 +165,7 @@ function G({
165
165
  function H({ className: t }) {
166
166
  const { product: e, selectedProductVariant: r } = u(), a = r?.price || e?.price, n = r?.compareAtPrice || e?.compareAtPrice;
167
167
  return /* @__PURE__ */ o(
168
- E,
168
+ T,
169
169
  {
170
170
  amount: a?.amount || "",
171
171
  currencyCode: a?.currencyCode || "",
@@ -1 +1 @@
1
- {"version":3,"file":"product-card.js","sources":["../../../src/components/commerce/product-card.tsx"],"sourcesContent":["import * as React from 'react'\nimport {useCallback, useContext, useMemo, useState} from 'react'\n\nimport {type Product, type ProductVariant} from '@shopify/shop-minis-platform'\n\nimport {useShopNavigation} from '../../hooks/navigation/useShopNavigation'\nimport {useSavedProductsActions} from '../../hooks/user/useSavedProductsActions'\nimport {formatMoney} from '../../lib/formatMoney'\nimport {cn} from '../../lib/utils'\nimport {FavoriteButton} from '../atoms/favorite-button'\nimport {Image} from '../atoms/image'\nimport {ProductVariantPrice} from '../atoms/product-variant-price'\nimport {Touchable} from '../atoms/touchable'\nimport {Badge} from '../ui/badge'\n\n// Context definition\ninterface ProductCardContextValue {\n // Core data\n product: Product\n selectedProductVariant?: ProductVariant\n\n // UI configuration\n variant: 'default' | 'priceOverlay' | 'compact'\n touchable: boolean\n badgeText?: string\n badgeVariant?: 'primary' | 'secondary' | 'destructive' | 'outline' | 'none'\n\n // State\n isFavorited: boolean\n\n // Actions\n onClick: () => void\n onFavoriteToggle: () => void\n}\n\nconst ProductCardContext = React.createContext<\n ProductCardContextValue | undefined\n>(undefined)\n\nfunction useProductCardContext() {\n const context = useContext(ProductCardContext)\n if (!context) {\n throw new Error(\n 'ProductCard components must be used within a ProductCard provider'\n )\n }\n return context\n}\n\n// Primitive components (building blocks)\nfunction ProductCardContainer({\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n const {touchable, onClick} = useProductCardContext()\n\n const content = (\n <div\n className={cn(\n 'relative w-full overflow-hidden rounded-xl border-0',\n className\n )}\n {...props}\n />\n )\n\n if (touchable && onClick) {\n return (\n <Touchable\n onClick={onClick}\n whileTap={{opacity: 0.7}}\n transition={{\n opacity: {type: 'tween', duration: 0.08, ease: 'easeInOut'},\n }}\n >\n {content}\n </Touchable>\n )\n }\n\n return content\n}\n\nfunction ProductCardImageContainer({\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n const {variant} = useProductCardContext()\n\n return (\n <div\n data-slot=\"product-card-image-container\"\n className={cn(\n // Ensure the product image is stretched to the full size of the container (can't use width/height: 100% because of flex)\n 'flex justify-stretch items-stretch',\n 'relative overflow-hidden rounded-xl border border-gray-200',\n 'w-full aspect-square',\n variant === 'compact' ? 'min-h-[104px]' : 'min-h-[134px]',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ProductCardImage({className, ...props}: React.ComponentProps<'img'>) {\n const {product, selectedProductVariant} = useProductCardContext()\n\n // Derive display image locally\n const displayImage = selectedProductVariant?.image || product.featuredImage\n const src = displayImage?.url\n const alt = displayImage?.altText || product.title\n const thumbhash = product.featuredImage?.thumbhash\n\n const renderImageElement = useCallback(\n (src: string) => {\n const imageElement = thumbhash ? (\n <Image\n data-slot=\"product-card-image\"\n src={src}\n alt={alt}\n aspectRatio={1}\n thumbhash={thumbhash}\n className={cn('size-full object-cover', className)}\n {...props}\n />\n ) : (\n <img\n data-slot=\"product-card-image\"\n src={src}\n alt={alt}\n className={cn('size-full', className)}\n {...props}\n />\n )\n\n return imageElement\n },\n [alt, className, props, thumbhash]\n )\n\n return (\n <div className=\"bg-gray-100 flex items-center justify-center size-full\">\n {src ? (\n renderImageElement(src)\n ) : (\n <div className=\"text-gray-400 text-sm w-full text-center\">No Image</div>\n )}\n </div>\n )\n}\n\nfunction ProductCardBadge({\n className,\n position = 'bottom-left',\n variant,\n children,\n ...props\n}: React.ComponentProps<typeof Badge> & {\n position?: 'top-left' | 'bottom-left'\n}) {\n const {badgeText, badgeVariant} = useProductCardContext()\n // If no children provided, use badgeText from context\n const content = children || badgeText\n\n if (!content) return null\n\n return (\n <div\n className={cn(\n 'absolute z-10',\n position === 'top-left' ? 'top-3 left-3' : 'bottom-2 left-2'\n )}\n >\n <Badge\n variant={variant ?? badgeVariant ?? 'none'}\n className={cn(\n !badgeVariant &&\n !variant &&\n 'bg-black/50 text-white border-transparent',\n 'rounded',\n className\n )}\n {...props}\n >\n {content}\n </Badge>\n </div>\n )\n}\n\nfunction ProductCardFavoriteButton({\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n const {isFavorited, onFavoriteToggle} = useProductCardContext()\n return (\n <div className={cn('absolute bottom-3 right-3 z-10', className)} {...props}>\n <FavoriteButton onClick={onFavoriteToggle} filled={isFavorited} />\n </div>\n )\n}\n\nfunction ProductCardInfo({className, ...props}: React.ComponentProps<'div'>) {\n const {variant} = useProductCardContext()\n if (variant !== 'default') {\n return null\n }\n\n return (\n <div\n data-slot=\"product-card-info\"\n className={cn('px-1 pt-2 pb-0 space-y-1', className)}\n {...props}\n />\n )\n}\n\nfunction ProductCardTitle({\n className,\n children,\n ...props\n}: React.ComponentProps<'h3'>) {\n const {product} = useProductCardContext()\n return (\n <h3\n data-slot=\"product-card-title\"\n className={cn(\n 'text-sm font-medium leading-tight text-gray-900',\n 'truncate overflow-hidden whitespace-nowrap text-ellipsis',\n className\n )}\n {...props}\n >\n {children || product.title}\n </h3>\n )\n}\n\nfunction ProductCardPrice({className}: {className?: string}) {\n const {product, selectedProductVariant} = useProductCardContext()\n\n // Derive price data locally\n const displayPrice = selectedProductVariant?.price || product?.price\n const displayCompareAtPrice =\n selectedProductVariant?.compareAtPrice || product?.compareAtPrice\n\n return (\n <ProductVariantPrice\n amount={displayPrice?.amount || ''}\n currencyCode={displayPrice?.currencyCode || ''}\n compareAtPriceAmount={displayCompareAtPrice?.amount}\n compareAtPriceCurrencyCode={displayCompareAtPrice?.currencyCode}\n className={className}\n />\n )\n}\n\n// Special PriceOverlayBadge for price overlay variant\nfunction ProductCardPriceOverlayBadge() {\n const {product, selectedProductVariant, variant} = useProductCardContext()\n if (variant !== 'priceOverlay') return null\n const displayPrice = selectedProductVariant?.price || product.price\n const currencyCode = displayPrice?.currencyCode\n const amount = displayPrice?.amount\n\n if (!currencyCode || !amount) return null\n return (\n <ProductCardBadge position=\"top-left\">\n {formatMoney(amount, currencyCode)}\n </ProductCardBadge>\n )\n}\n\nexport interface ProductCardProps {\n /** The product to display in the card */\n product: Product\n /** Optional selected variant of the product to show specific variant data */\n selectedProductVariant?: ProductVariant\n /** Visual style variant of the card */\n variant?: 'default' | 'priceOverlay' | 'compact'\n /** Whether the card can be clicked/tapped to navigate to product details */\n touchable?: boolean\n /** Optional text to display in a badge on the card */\n badgeText?: string\n /** Visual style variant for the badge */\n badgeVariant?: 'primary' | 'secondary' | 'destructive' | 'outline' | 'none'\n /** Callback fired when the product is clicked */\n onProductClick?: () => void\n /** Callback fired when the favorite button is toggled */\n onFavoriteToggled?: (isFavorited: boolean) => void\n /** Custom layout via children */\n children?: React.ReactNode\n}\n\nfunction ProductCard({\n product,\n selectedProductVariant,\n variant = 'default',\n touchable = true,\n badgeText,\n badgeVariant,\n onProductClick,\n onFavoriteToggled,\n children,\n}: ProductCardProps) {\n const {navigateToProduct} = useShopNavigation()\n const {saveProduct, unsaveProduct} = useSavedProductsActions()\n\n // Local state for optimistic UI updates\n const [isFavoritedLocal, setIsFavoritedLocal] = useState(product.isFavorited)\n\n const handleClick = useCallback(() => {\n if (!touchable) return\n\n onProductClick?.()\n\n navigateToProduct({\n productId: product.id,\n })\n }, [navigateToProduct, product.id, touchable, onProductClick])\n\n const handleFavoriteClick = useCallback(async () => {\n const previousState = isFavoritedLocal\n\n // Optimistic update\n setIsFavoritedLocal(!previousState)\n onFavoriteToggled?.(!previousState)\n\n try {\n if (previousState) {\n await unsaveProduct({\n productId: product.id,\n shopId: product.shop.id,\n productVariantId:\n selectedProductVariant?.id || product.defaultVariantId,\n })\n } else {\n await saveProduct({\n productId: product.id,\n shopId: product.shop.id,\n productVariantId:\n selectedProductVariant?.id || product.defaultVariantId,\n })\n }\n } catch (error) {\n // Revert optimistic update on error\n setIsFavoritedLocal(previousState)\n onFavoriteToggled?.(previousState)\n }\n }, [\n isFavoritedLocal,\n product.id,\n product.shop.id,\n product.defaultVariantId,\n selectedProductVariant?.id,\n saveProduct,\n unsaveProduct,\n onFavoriteToggled,\n ])\n\n const contextValue = useMemo<ProductCardContextValue>(\n () => ({\n // Core data\n product,\n selectedProductVariant,\n\n // UI configuration\n variant,\n touchable,\n badgeText,\n badgeVariant,\n\n // State\n isFavorited: isFavoritedLocal,\n\n // Actions\n onClick: handleClick,\n onFavoriteToggle: handleFavoriteClick,\n }),\n [\n product,\n selectedProductVariant,\n variant,\n touchable,\n badgeText,\n badgeVariant,\n isFavoritedLocal,\n handleClick,\n handleFavoriteClick,\n ]\n )\n\n return (\n <ProductCardContext.Provider value={contextValue}>\n {children ?? (\n <ProductCardContainer>\n <ProductCardImageContainer>\n <ProductCardImage />\n {variant === 'priceOverlay' && <ProductCardPriceOverlayBadge />}\n <ProductCardBadge />\n <ProductCardFavoriteButton />\n </ProductCardImageContainer>\n {variant === 'default' && (\n <ProductCardInfo>\n <ProductCardTitle />\n <ProductCardPrice />\n </ProductCardInfo>\n )}\n </ProductCardContainer>\n )}\n </ProductCardContext.Provider>\n )\n}\n\nexport {\n ProductCard,\n ProductCardContainer,\n ProductCardImageContainer,\n ProductCardImage,\n ProductCardBadge,\n ProductCardFavoriteButton,\n ProductCardInfo,\n ProductCardTitle,\n ProductCardPrice,\n}\n"],"names":["ProductCardContext","React","useProductCardContext","context","useContext","ProductCardContainer","className","props","touchable","onClick","content","jsx","cn","Touchable","ProductCardImageContainer","variant","ProductCardImage","product","selectedProductVariant","displayImage","src","alt","thumbhash","renderImageElement","useCallback","Image","ProductCardBadge","position","children","badgeText","badgeVariant","Badge","ProductCardFavoriteButton","isFavorited","onFavoriteToggle","FavoriteButton","ProductCardInfo","ProductCardTitle","ProductCardPrice","displayPrice","displayCompareAtPrice","ProductVariantPrice","ProductCardPriceOverlayBadge","currencyCode","amount","formatMoney","ProductCard","onProductClick","onFavoriteToggled","navigateToProduct","useShopNavigation","saveProduct","unsaveProduct","useSavedProductsActions","isFavoritedLocal","setIsFavoritedLocal","useState","handleClick","handleFavoriteClick","previousState","contextValue","useMemo","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"product-card.js","sources":["../../../src/components/commerce/product-card.tsx"],"sourcesContent":["import * as React from 'react'\nimport {useCallback, useContext, useMemo, useState} from 'react'\n\nimport {type Product, type ProductVariant} from '@shopify/shop-minis-platform'\n\nimport {useShopNavigation} from '../../hooks/navigation/useShopNavigation'\nimport {useSavedProductsActions} from '../../hooks/user/useSavedProductsActions'\nimport {formatMoney} from '../../lib/formatMoney'\nimport {cn} from '../../lib/utils'\nimport {Image} from '../atoms/image'\nimport {ProductVariantPrice} from '../atoms/product-variant-price'\nimport {Touchable} from '../atoms/touchable'\nimport {Badge} from '../ui/badge'\n\nimport {FavoriteButton} from './favorite-button'\n\n// Context definition\ninterface ProductCardContextValue {\n // Core data\n product: Product\n selectedProductVariant?: ProductVariant\n\n // UI configuration\n variant: 'default' | 'priceOverlay' | 'compact'\n touchable: boolean\n badgeText?: string\n badgeVariant?: 'primary' | 'secondary' | 'destructive' | 'outline' | 'none'\n\n // State\n isFavorited: boolean\n\n // Actions\n onClick: () => void\n onFavoriteToggle: () => void\n}\n\nconst ProductCardContext = React.createContext<\n ProductCardContextValue | undefined\n>(undefined)\n\nfunction useProductCardContext() {\n const context = useContext(ProductCardContext)\n if (!context) {\n throw new Error(\n 'ProductCard components must be used within a ProductCard provider'\n )\n }\n return context\n}\n\n// Primitive components (building blocks)\nfunction ProductCardContainer({\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n const {touchable, onClick} = useProductCardContext()\n\n const content = (\n <div\n className={cn(\n 'relative w-full overflow-hidden rounded-xl border-0',\n className\n )}\n {...props}\n />\n )\n\n if (touchable && onClick) {\n return (\n <Touchable\n onClick={onClick}\n whileTap={{opacity: 0.7}}\n transition={{\n opacity: {type: 'tween', duration: 0.08, ease: 'easeInOut'},\n }}\n >\n {content}\n </Touchable>\n )\n }\n\n return content\n}\n\nfunction ProductCardImageContainer({\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n const {variant} = useProductCardContext()\n\n return (\n <div\n data-slot=\"product-card-image-container\"\n className={cn(\n // Ensure the product image is stretched to the full size of the container (can't use width/height: 100% because of flex)\n 'flex justify-stretch items-stretch',\n 'relative overflow-hidden rounded-xl border border-gray-200',\n 'w-full aspect-square',\n variant === 'compact' ? 'min-h-[104px]' : 'min-h-[134px]',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ProductCardImage({className, ...props}: React.ComponentProps<'img'>) {\n const {product, selectedProductVariant} = useProductCardContext()\n\n // Derive display image locally\n const displayImage = selectedProductVariant?.image || product.featuredImage\n const src = displayImage?.url\n const alt = displayImage?.altText || product.title\n const thumbhash = product.featuredImage?.thumbhash\n\n const renderImageElement = useCallback(\n (src: string) => {\n const imageElement = thumbhash ? (\n <Image\n data-slot=\"product-card-image\"\n src={src}\n alt={alt}\n aspectRatio={1}\n thumbhash={thumbhash}\n className={cn('size-full object-cover', className)}\n {...props}\n />\n ) : (\n <img\n data-slot=\"product-card-image\"\n src={src}\n alt={alt}\n className={cn('size-full', className)}\n {...props}\n />\n )\n\n return imageElement\n },\n [alt, className, props, thumbhash]\n )\n\n return (\n <div className=\"bg-gray-100 flex items-center justify-center size-full\">\n {src ? (\n renderImageElement(src)\n ) : (\n <div className=\"text-gray-400 text-sm w-full text-center\">No Image</div>\n )}\n </div>\n )\n}\n\nfunction ProductCardBadge({\n className,\n position = 'bottom-left',\n variant,\n children,\n ...props\n}: React.ComponentProps<typeof Badge> & {\n position?: 'top-left' | 'bottom-left'\n}) {\n const {badgeText, badgeVariant} = useProductCardContext()\n // If no children provided, use badgeText from context\n const content = children || badgeText\n\n if (!content) return null\n\n return (\n <div\n className={cn(\n 'absolute z-10',\n position === 'top-left' ? 'top-3 left-3' : 'bottom-2 left-2'\n )}\n >\n <Badge\n variant={variant ?? badgeVariant ?? 'none'}\n className={cn(\n !badgeVariant &&\n !variant &&\n 'bg-black/50 text-white border-transparent',\n 'rounded',\n className\n )}\n {...props}\n >\n {content}\n </Badge>\n </div>\n )\n}\n\nfunction ProductCardFavoriteButton({\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n const {isFavorited, onFavoriteToggle} = useProductCardContext()\n return (\n <div className={cn('absolute bottom-3 right-3 z-10', className)} {...props}>\n <FavoriteButton onClick={onFavoriteToggle} filled={isFavorited} />\n </div>\n )\n}\n\nfunction ProductCardInfo({className, ...props}: React.ComponentProps<'div'>) {\n const {variant} = useProductCardContext()\n if (variant !== 'default') {\n return null\n }\n\n return (\n <div\n data-slot=\"product-card-info\"\n className={cn('px-1 pt-2 pb-0 space-y-1', className)}\n {...props}\n />\n )\n}\n\nfunction ProductCardTitle({\n className,\n children,\n ...props\n}: React.ComponentProps<'h3'>) {\n const {product} = useProductCardContext()\n return (\n <h3\n data-slot=\"product-card-title\"\n className={cn(\n 'text-sm font-medium leading-tight text-gray-900',\n 'truncate overflow-hidden whitespace-nowrap text-ellipsis',\n className\n )}\n {...props}\n >\n {children || product.title}\n </h3>\n )\n}\n\nfunction ProductCardPrice({className}: {className?: string}) {\n const {product, selectedProductVariant} = useProductCardContext()\n\n // Derive price data locally\n const displayPrice = selectedProductVariant?.price || product?.price\n const displayCompareAtPrice =\n selectedProductVariant?.compareAtPrice || product?.compareAtPrice\n\n return (\n <ProductVariantPrice\n amount={displayPrice?.amount || ''}\n currencyCode={displayPrice?.currencyCode || ''}\n compareAtPriceAmount={displayCompareAtPrice?.amount}\n compareAtPriceCurrencyCode={displayCompareAtPrice?.currencyCode}\n className={className}\n />\n )\n}\n\n// Special PriceOverlayBadge for price overlay variant\nfunction ProductCardPriceOverlayBadge() {\n const {product, selectedProductVariant, variant} = useProductCardContext()\n if (variant !== 'priceOverlay') return null\n const displayPrice = selectedProductVariant?.price || product.price\n const currencyCode = displayPrice?.currencyCode\n const amount = displayPrice?.amount\n\n if (!currencyCode || !amount) return null\n return (\n <ProductCardBadge position=\"top-left\">\n {formatMoney(amount, currencyCode)}\n </ProductCardBadge>\n )\n}\n\nexport interface ProductCardProps {\n /** The product to display in the card */\n product: Product\n /** Optional selected variant of the product to show specific variant data */\n selectedProductVariant?: ProductVariant\n /** Visual style variant of the card */\n variant?: 'default' | 'priceOverlay' | 'compact'\n /** Whether the card can be clicked/tapped to navigate to product details */\n touchable?: boolean\n /** Optional text to display in a badge on the card */\n badgeText?: string\n /** Visual style variant for the badge */\n badgeVariant?: 'primary' | 'secondary' | 'destructive' | 'outline' | 'none'\n /** Callback fired when the product is clicked */\n onProductClick?: () => void\n /** Callback fired when the favorite button is toggled */\n onFavoriteToggled?: (isFavorited: boolean) => void\n /** Custom layout via children */\n children?: React.ReactNode\n}\n\nfunction ProductCard({\n product,\n selectedProductVariant,\n variant = 'default',\n touchable = true,\n badgeText,\n badgeVariant,\n onProductClick,\n onFavoriteToggled,\n children,\n}: ProductCardProps) {\n const {navigateToProduct} = useShopNavigation()\n const {saveProduct, unsaveProduct} = useSavedProductsActions()\n\n // Local state for optimistic UI updates\n const [isFavoritedLocal, setIsFavoritedLocal] = useState(product.isFavorited)\n\n const handleClick = useCallback(() => {\n if (!touchable) return\n\n onProductClick?.()\n\n navigateToProduct({\n productId: product.id,\n })\n }, [navigateToProduct, product.id, touchable, onProductClick])\n\n const handleFavoriteClick = useCallback(async () => {\n const previousState = isFavoritedLocal\n\n // Optimistic update\n setIsFavoritedLocal(!previousState)\n onFavoriteToggled?.(!previousState)\n\n try {\n if (previousState) {\n await unsaveProduct({\n productId: product.id,\n shopId: product.shop.id,\n productVariantId:\n selectedProductVariant?.id || product.defaultVariantId,\n })\n } else {\n await saveProduct({\n productId: product.id,\n shopId: product.shop.id,\n productVariantId:\n selectedProductVariant?.id || product.defaultVariantId,\n })\n }\n } catch (error) {\n // Revert optimistic update on error\n setIsFavoritedLocal(previousState)\n onFavoriteToggled?.(previousState)\n }\n }, [\n isFavoritedLocal,\n product.id,\n product.shop.id,\n product.defaultVariantId,\n selectedProductVariant?.id,\n saveProduct,\n unsaveProduct,\n onFavoriteToggled,\n ])\n\n const contextValue = useMemo<ProductCardContextValue>(\n () => ({\n // Core data\n product,\n selectedProductVariant,\n\n // UI configuration\n variant,\n touchable,\n badgeText,\n badgeVariant,\n\n // State\n isFavorited: isFavoritedLocal,\n\n // Actions\n onClick: handleClick,\n onFavoriteToggle: handleFavoriteClick,\n }),\n [\n product,\n selectedProductVariant,\n variant,\n touchable,\n badgeText,\n badgeVariant,\n isFavoritedLocal,\n handleClick,\n handleFavoriteClick,\n ]\n )\n\n return (\n <ProductCardContext.Provider value={contextValue}>\n {children ?? (\n <ProductCardContainer>\n <ProductCardImageContainer>\n <ProductCardImage />\n {variant === 'priceOverlay' && <ProductCardPriceOverlayBadge />}\n <ProductCardBadge />\n <ProductCardFavoriteButton />\n </ProductCardImageContainer>\n {variant === 'default' && (\n <ProductCardInfo>\n <ProductCardTitle />\n <ProductCardPrice />\n </ProductCardInfo>\n )}\n </ProductCardContainer>\n )}\n </ProductCardContext.Provider>\n )\n}\n\nexport {\n ProductCard,\n ProductCardContainer,\n ProductCardImageContainer,\n ProductCardImage,\n ProductCardBadge,\n ProductCardFavoriteButton,\n ProductCardInfo,\n ProductCardTitle,\n ProductCardPrice,\n}\n"],"names":["ProductCardContext","React","useProductCardContext","context","useContext","ProductCardContainer","className","props","touchable","onClick","content","jsx","cn","Touchable","ProductCardImageContainer","variant","ProductCardImage","product","selectedProductVariant","displayImage","src","alt","thumbhash","renderImageElement","useCallback","Image","ProductCardBadge","position","children","badgeText","badgeVariant","Badge","ProductCardFavoriteButton","isFavorited","onFavoriteToggle","FavoriteButton","ProductCardInfo","ProductCardTitle","ProductCardPrice","displayPrice","displayCompareAtPrice","ProductVariantPrice","ProductCardPriceOverlayBadge","currencyCode","amount","formatMoney","ProductCard","onProductClick","onFavoriteToggled","navigateToProduct","useShopNavigation","saveProduct","unsaveProduct","useSavedProductsActions","isFavoritedLocal","setIsFavoritedLocal","useState","handleClick","handleFavoriteClick","previousState","contextValue","useMemo","jsxs"],"mappings":"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"}
@@ -5,9 +5,9 @@ import { useShopNavigation as M } from "../../hooks/navigation/useShopNavigation
5
5
  import { useSavedProductsActions as D } from "../../hooks/user/useSavedProductsActions.js";
6
6
  import { formatMoney as z } from "../../lib/formatMoney.js";
7
7
  import { cn as n } from "../../lib/utils.js";
8
- import { FavoriteButton as q } from "../atoms/favorite-button.js";
9
8
  import { Touchable as T } from "../atoms/touchable.js";
10
- import { Card as B, CardContent as U, CardAction as _ } from "../ui/card.js";
9
+ import { Card as q, CardContent as B, CardAction as U } from "../ui/card.js";
10
+ import { FavoriteButton as _ } from "./favorite-button.js";
11
11
  import E from "../../shop-minis-react/node_modules/.pnpm/lucide-react@0.513.0_react@19.1.0/node_modules/lucide-react/dist/esm/icons/star.js";
12
12
  import { Root as G } from "../../shop-minis-react/node_modules/.pnpm/@radix-ui_react-slot@1.2.3_@types_react@19.1.6_react@19.1.0/node_modules/@radix-ui/react-slot/dist/index.js";
13
13
  const H = O("", {
@@ -44,7 +44,7 @@ function J({
44
44
  opacity: { type: "tween", duration: 0.08, ease: "easeInOut" }
45
45
  },
46
46
  children: /* @__PURE__ */ t(
47
- a ? G : B,
47
+ a ? G : q,
48
48
  {
49
49
  className: n(
50
50
  H({ layout: o, discount: r }),
@@ -81,7 +81,7 @@ function Q({
81
81
  ...r
82
82
  }) {
83
83
  return /* @__PURE__ */ t(
84
- U,
84
+ B,
85
85
  {
86
86
  className: n(
87
87
  o === "horizontal" ? "flex-1 min-w-0 space-y-1 px-0 py-0" : "space-y-2",
@@ -178,7 +178,7 @@ function et({
178
178
  ...a
179
179
  }) {
180
180
  return /* @__PURE__ */ t(
181
- _,
181
+ U,
182
182
  {
183
183
  className: n("flex-shrink-0 self-center px-0 py-0", e),
184
184
  ...a,
@@ -192,7 +192,7 @@ function et({
192
192
  opacity: { type: "tween", duration: 0.08, ease: "easeInOut" },
193
193
  scale: { type: "tween", duration: 0.08, ease: "easeInOut" }
194
194
  },
195
- children: /* @__PURE__ */ t(q, { filled: r, onClick: o })
195
+ children: /* @__PURE__ */ t(_, { filled: r, onClick: o })
196
196
  }
197
197
  )
198
198
  }