kupos-ui-components-lib 10.4.13 → 10.4.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/images/anims/service_list/60_percent_anim.json +1 -0
- package/dist/assets/images/filter/arrow-down.png +0 -0
- package/dist/assets/images/filter/rapido.svg +14 -0
- package/dist/components/FilterSortBar/FilterChip.d.ts +6 -2
- package/dist/components/FilterSortBar/FilterChip.js +10 -32
- package/dist/components/FilterSortBar/FilterSortBarMobile.d.ts +1 -1
- package/dist/components/FilterSortBar/FilterSortBarMobile.js +71 -38
- package/dist/components/FilterSortBar/FiltersMasterSheet.d.ts +3 -1
- package/dist/components/FilterSortBar/FiltersMasterSheet.js +28 -97
- package/dist/components/FilterSortBar/OptionCheckboxList.js +5 -16
- package/dist/components/FilterSortBar/PriceRangeSlider.js +17 -55
- package/dist/components/FilterSortBar/SheetFooter.js +3 -30
- package/dist/components/FilterSortBar/defaultIcons.js +9 -0
- package/dist/components/FilterSortBar/icons.d.ts +7 -0
- package/dist/components/FilterSortBar/icons.js +8 -1
- package/dist/components/FilterSortBar/index.d.ts +1 -1
- package/dist/components/FilterSortBar/types.d.ts +34 -0
- package/dist/components/PaymentOptions/PaymentOptionsDesktop.d.ts +4 -0
- package/dist/components/PaymentOptions/PaymentOptionsDesktop.js +5 -0
- package/dist/components/PaymentOptions/PaymentOptionsMobile.d.ts +4 -0
- package/dist/components/PaymentOptions/PaymentOptionsMobile.js +5 -0
- package/dist/components/PaymentOptions/ResponsivePaymentOptions.d.ts +3 -0
- package/dist/components/PaymentOptions/ResponsivePaymentOptions.js +10 -0
- package/dist/components/PaymentOptions/index.d.ts +5 -0
- package/dist/components/PaymentOptions/index.js +4 -0
- package/dist/components/PaymentOptions/mobileTypes.d.ts +0 -0
- package/dist/components/PaymentOptions/mobileTypes.js +0 -0
- package/dist/components/PaymentOptions/type.d.ts +4 -0
- package/dist/components/PaymentOptions/type.js +1 -0
- package/dist/components/PaymentSideBar/PaymentSideBarMobile.js +1 -1
- package/dist/components/ServiceItem/ExpandedDropdown.d.ts +19 -0
- package/dist/components/ServiceItem/ExpandedDropdown.js +28 -0
- package/dist/components/ServiceItem/ServiceItemDesktopPeru.d.ts +6 -0
- package/dist/components/ServiceItem/ServiceItemDesktopPeru.js +612 -0
- package/dist/index.d.ts +1 -1
- package/dist/styles.css +233 -0
- package/dist/ui/PaymentCardMobile/PaymentCardMobile.js +18 -4
- package/dist/ui/TopAmenities/PromoCountdown.d.ts +18 -0
- package/dist/ui/TopAmenities/PromoCountdown.js +55 -0
- package/package.json +1 -1
- package/src/assets/images/filter/arrow-down.png +0 -0
- package/src/assets/images/filter/rapido.svg +14 -0
- package/src/components/FilterSortBar/FilterChip.tsx +31 -35
- package/src/components/FilterSortBar/FilterSortBarMobile.tsx +106 -66
- package/src/components/FilterSortBar/FiltersMasterSheet.tsx +34 -118
- package/src/components/FilterSortBar/OptionCheckboxList.tsx +5 -16
- package/src/components/FilterSortBar/PriceRangeSlider.tsx +20 -61
- package/src/components/FilterSortBar/SheetFooter.tsx +4 -32
- package/src/components/FilterSortBar/defaultIcons.ts +11 -0
- package/src/components/FilterSortBar/icons.tsx +38 -2
- package/src/components/FilterSortBar/index.ts +2 -0
- package/src/components/FilterSortBar/types.ts +36 -0
- package/src/components/PaymentSideBar/PaymentSideBarMobile.tsx +4 -1
- package/src/index.ts +2 -0
- package/src/ui/PaymentCardMobile/PaymentCardMobile.tsx +101 -31
- package/src/components/FilterSortBar/SingleFilterSheet.tsx +0 -82
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"nm":"Main Scene","h":100,"w":100,"meta":{"g":"@lottiefiles/creator@1.89.0"},"layers":[{"ty":4,"nm":"Shape Layer 1","sr":1,"st":0,"op":150,"ip":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[37,9]},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[100,100],"t":1},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[109,109],"t":48},{"s":[100,100],"t":89}]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[50,50]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}},"shapes":[{"ty":"gr","nm":"Group 1","it":[{"ty":"sh","nm":"Path 1","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0.51,0.27],[0.31,0.46],[0.14,0.56],[0,0.59],[-0.31,0.79],[-0.58,0.44],[-0.83,0],[-0.49,-0.27],[-0.26,-0.44],[-0.05,-0.49],[0,0],[0.25,0.2],[0.39,0],[0.27,-0.23],[0.15,-0.45],[0.02,-0.66],[0,-0.02],[0,-0.01],[-0.24,0.18],[-0.3,0.1],[-0.32,0],[-0.47,-0.26],[-0.28,-0.49],[0,-0.65],[0.3,-0.51],[0.52,-0.3],[0.67,0]],"o":[[-0.75,0],[-0.51,-0.28],[-0.31,-0.46],[-0.13,-0.57],[0,-1.1],[0.31,-0.8],[0.59,-0.44],[0.71,0],[0.49,0.27],[0.26,0.44],[0,0],[-0.07,-0.37],[-0.24,-0.21],[-0.37,0],[-0.27,0.22],[-0.15,0.45],[0,0.01],[0,0.02],[0.14,-0.24],[0.24,-0.18],[0.3,-0.1],[0.54,0],[0.47,0.25],[0.29,0.48],[0,0.61],[-0.29,0.5],[-0.51,0.3],[0,0]],"v":[[10.74,14.17],[8.85,13.76],[7.61,12.66],[6.94,11.13],[6.75,9.39],[7.21,6.55],[8.54,4.69],[10.67,4.03],[12.46,4.44],[13.58,5.5],[14.04,6.9],[12.08,6.9],[11.6,6.05],[10.65,5.74],[9.69,6.09],[9.06,7.1],[8.8,8.76],[8.8,8.81],[8.8,8.85],[9.38,8.22],[10.19,7.8],[11.11,7.64],[12.63,8.04],[13.75,9.14],[14.18,10.84],[13.73,12.52],[12.51,13.72],[10.74,14.17]]}}},{"ty":"sh","nm":"Path 2","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-0.23,0.12],[-0.13,0.22],[0,0.28],[0.14,0.21],[0.24,0.12],[0.31,0],[0.23,-0.12],[0.14,-0.22],[0,-0.29],[-0.14,-0.23],[-0.23,-0.13],[-0.31,0]],"o":[[0.3,0],[0.23,-0.13],[0.14,-0.22],[0,-0.31],[-0.13,-0.22],[-0.23,-0.13],[-0.3,0],[-0.23,0.12],[-0.14,0.22],[0,0.29],[0.14,0.22],[0.24,0.12],[0,0]],"v":[[10.62,12.38],[11.42,12.19],[11.97,11.66],[12.18,10.91],[11.97,10.12],[11.41,9.6],[10.6,9.41],[9.8,9.59],[9.24,10.11],[9.03,10.88],[9.24,11.66],[9.8,12.19],[10.62,12.38]]}}},{"ty":"sh","nm":"Path 3","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0.64,0.43],[0.35,0.76],[0,1],[-0.35,0.76],[-0.64,0.43],[-0.91,0],[-0.64,-0.43],[-0.35,-0.77],[0,-1],[0.35,-0.77],[0.64,-0.43],[0.91,0]],"o":[[-0.91,0],[-0.64,-0.43],[-0.35,-0.77],[0,-1],[0.35,-0.77],[0.64,-0.43],[0.91,0],[0.64,0.43],[0.35,0.76],[0,1],[-0.35,0.76],[-0.64,0.43],[0,0]],"v":[[19.93,14.17],[17.61,13.52],[16.11,11.75],[15.59,9.1],[16.11,6.47],[17.61,4.68],[19.93,4.03],[22.25,4.68],[23.74,6.47],[24.27,9.1],[23.74,11.75],[22.25,13.52],[19.93,14.17]]}}},{"ty":"sh","nm":"Path 4","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-0.33,0.26],[-0.18,0.47],[0,0.65],[0.19,0.47],[0.34,0.25],[0.44,0],[0.34,-0.26],[0.19,-0.48],[0,-0.65],[-0.18,-0.48],[-0.33,-0.26],[-0.44,0]],"o":[[0.44,0],[0.34,-0.26],[0.19,-0.48],[0,-0.65],[-0.18,-0.48],[-0.33,-0.26],[-0.44,0],[-0.33,0.25],[-0.18,0.47],[0,0.65],[0.19,0.47],[0.34,0.26],[0,0]],"v":[[19.93,12.28],[21.08,11.89],[21.85,10.79],[22.13,9.1],[21.85,7.42],[21.08,6.33],[19.93,5.94],[18.77,6.33],[18,7.42],[17.73,9.1],[18,10.79],[18.77,11.89],[19.93,12.28]]}}},{"ty":"sh","nm":"Path 5","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[27.69,14],[33.13,4.2],[35.18,4.2],[29.73,14],[27.69,14]]}}},{"ty":"sh","nm":"Path 6","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0.38,0.21],[0.22,0.38],[0,0.52],[-0.22,0.37],[-0.37,0.21],[-0.46,0],[-0.37,-0.21],[-0.21,-0.38],[0,-0.54],[0.22,-0.38],[0.37,-0.21],[0.47,0]],"o":[[-0.47,0],[-0.37,-0.21],[-0.22,-0.38],[0,-0.54],[0.22,-0.38],[0.38,-0.21],[0.48,0],[0.37,0.21],[0.22,0.37],[0,0.52],[-0.22,0.38],[-0.36,0.21],[0,0]],"v":[[34.94,14.17],[33.66,13.86],[32.77,12.98],[32.43,11.62],[32.77,10.25],[33.66,9.37],[34.92,9.06],[36.2,9.37],[37.08,10.25],[37.42,11.62],[37.08,12.98],[36.18,13.86],[34.94,14.17]]}}},{"ty":"sh","nm":"Path 7","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-0.13,0.08],[-0.07,0.17],[0,0.24],[0.07,0.17],[0.13,0.08],[0.17,0],[0.13,-0.09],[0.07,-0.17],[0,-0.25],[-0.07,-0.17],[-0.13,-0.09],[-0.17,0]],"o":[[0.17,0],[0.13,-0.09],[0.07,-0.17],[0,-0.26],[-0.07,-0.17],[-0.13,-0.09],[-0.17,0],[-0.13,0.08],[-0.07,0.17],[0,0.25],[0.07,0.17],[0.13,0.08],[0,0]],"v":[[34.92,12.75],[35.37,12.63],[35.68,12.24],[35.79,11.62],[35.68,10.98],[35.37,10.6],[34.92,10.46],[34.48,10.6],[34.17,10.98],[34.06,11.61],[34.17,12.24],[34.48,12.63],[34.92,12.75]]}}},{"ty":"sh","nm":"Path 8","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0.38,0.21],[0.22,0.38],[0,0.52],[-0.22,0.37],[-0.37,0.21],[-0.47,0],[-0.37,-0.21],[-0.21,-0.38],[0,-0.54],[0.22,-0.38],[0.37,-0.21],[0.47,0]],"o":[[-0.47,0],[-0.37,-0.21],[-0.22,-0.38],[0,-0.54],[0.22,-0.38],[0.38,-0.21],[0.47,0],[0.37,0.21],[0.22,0.37],[0,0.52],[-0.21,0.38],[-0.37,0.21],[0,0]],"v":[[27.99,9.14],[26.72,8.83],[25.82,7.95],[25.49,6.59],[25.82,5.22],[26.72,4.34],[27.99,4.03],[29.25,4.34],[30.14,5.22],[30.47,6.59],[30.14,7.95],[29.25,8.83],[27.99,9.14]]}}},{"ty":"sh","nm":"Path 9","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-0.13,0.08],[-0.07,0.17],[0,0.24],[0.07,0.17],[0.13,0.08],[0.17,0],[0.13,-0.09],[0.07,-0.17],[0,-0.26],[-0.07,-0.17],[-0.13,-0.09],[-0.17,0]],"o":[[0.17,0],[0.13,-0.09],[0.07,-0.17],[0,-0.26],[-0.07,-0.17],[-0.13,-0.09],[-0.17,0],[-0.13,0.08],[-0.07,0.17],[0,0.24],[0.07,0.17],[0.13,0.08],[0,0]],"v":[[27.98,7.73],[28.43,7.6],[28.74,7.21],[28.85,6.59],[28.74,5.95],[28.43,5.57],[27.98,5.43],[27.53,5.57],[27.22,5.95],[27.11,6.59],[27.22,7.21],[27.53,7.6],[27.98,7.73]]}}},{"ty":"sh","nm":"Path 10","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0.73,0.43],[0.42,0.76],[0,1],[-0.41,0.76],[-0.73,0.43],[-0.96,0],[-0.74,-0.43],[-0.4,-0.77],[0,-1],[0.41,-0.77],[0.74,-0.43],[0.96,0]],"o":[[-0.96,0],[-0.73,-0.43],[-0.41,-0.77],[0,-1],[0.42,-0.77],[0.73,-0.43],[0.96,0],[0.74,0.43],[0.41,0.76],[0,1],[-0.4,0.76],[-0.74,0.43],[0,0]],"v":[[46.66,14.17],[44.12,13.52],[42.4,11.75],[41.79,9.1],[42.4,6.47],[44.12,4.68],[46.66,4.03],[49.21,4.68],[50.91,6.47],[51.53,9.1],[50.91,11.75],[49.21,13.52],[46.66,14.17]]}}},{"ty":"sh","nm":"Path 11","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-0.4,0.26],[-0.22,0.47],[0,0.65],[0.22,0.47],[0.41,0.25],[0.57,0],[0.41,-0.26],[0.22,-0.48],[0,-0.65],[-0.22,-0.48],[-0.41,-0.26],[-0.55,0]],"o":[[0.57,0],[0.41,-0.26],[0.22,-0.48],[0,-0.65],[-0.22,-0.48],[-0.4,-0.26],[-0.55,0],[-0.41,0.25],[-0.22,0.47],[0,0.65],[0.22,0.47],[0.41,0.26],[0,0]],"v":[[46.66,12.28],[48.11,11.89],[49.07,10.79],[49.4,9.1],[49.07,7.42],[48.11,6.33],[46.66,5.94],[45.22,6.33],[44.26,7.42],[43.93,9.1],[44.26,10.79],[45.22,11.89],[46.66,12.28]]}}},{"ty":"sh","nm":"Path 12","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[53.1,14],[53.1,4.2],[59.61,4.2],[59.61,5.89],[55.2,5.89],[55.2,8.27],[58.67,8.27],[58.67,9.91],[55.2,9.91],[55.2,14],[53.1,14]]}}},{"ty":"sh","nm":"Path 13","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[60.99,14],[60.99,4.2],[67.5,4.2],[67.5,5.89],[63.09,5.89],[63.09,8.27],[66.56,8.27],[66.56,9.91],[63.09,9.91],[63.09,14],[60.99,14]]}}},{"ty":"fl","nm":"Fill","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":100}},{"ty":"tr","a":{"a":0,"k":[37.094,9.075]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[37.094,9.075]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}}]},{"ty":"gr","nm":"Group 2","it":[{"ty":"sh","nm":"Path 14","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,0],[0,-3.53],[0,0],[3.53,0],[0,0],[0,3.53],[0,0],[-3.53,0]],"o":[[0,0],[3.53,0],[0,0],[0,3.53],[0,0],[-3.53,0],[0,0],[0,-3.53],[0,0]],"v":[[6.4,0],[67.6,0],[74,6.4],[74,11.6],[67.6,18],[6.4,18],[0,11.6],[0,6.4],[6.4,0]]}}},{"ty":"fl","nm":"Fill","c":{"a":0,"k":[1,0.361,0.38]},"r":1,"o":{"a":0,"k":100}},{"ty":"tr","a":{"a":0,"k":[37,9]},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[37,9]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}}]}],"ind":1}],"v":"5.7.0","fr":30,"op":89,"ip":0,"assets":[]}
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<svg width="13" height="12" viewBox="0 0 13 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M7.26471 1.41528C9.92084 1.41532 12.0821 3.57653 12.0821 6.23267C12.0821 8.88878 9.92082 11.05 7.26471 11.05C4.60857 11.05 2.44735 8.8888 2.44733 6.23267C2.44733 3.57651 4.60855 1.41528 7.26471 1.41528ZM7.26471 1.9895C4.92362 1.9895 3.02155 3.89158 3.02155 6.23267C3.02157 8.57373 4.92364 10.4758 7.26471 10.4758C9.60575 10.4758 11.5078 8.57371 11.5079 6.23267C11.5079 3.8916 9.60577 1.98953 7.26471 1.9895Z" fill="#464647" stroke="#464647" stroke-width="0.1"/>
|
|
3
|
+
<path d="M7.26425 2.51123C9.31779 2.51134 10.9859 4.17935 10.9859 6.23291C10.9858 8.28638 9.31772 9.95448 7.26425 9.95459C5.21449 9.95459 3.54268 8.28648 3.54257 6.23291C3.54257 4.17928 5.21063 2.51123 7.26425 2.51123ZM7.26425 3.08545C5.52946 3.08545 4.11679 4.49812 4.11679 6.23291C4.1169 7.96761 5.52953 9.38037 7.26425 9.38037C8.99888 9.38026 10.4116 7.96754 10.4117 6.23291C10.4117 4.49819 8.99895 3.08556 7.26425 3.08545Z" fill="#464647" stroke="#464647" stroke-width="0.1"/>
|
|
4
|
+
<path d="M7.26443 5.56592C6.89538 5.56592 6.5979 5.86341 6.5979 6.23246C6.5979 6.60151 6.89538 6.89901 7.26443 6.89901C7.63349 6.89901 7.93099 6.60151 7.93099 6.23246C7.93099 5.86341 7.63349 5.56592 7.26443 5.56592Z" fill="#464647"/>
|
|
5
|
+
<path d="M6.53391 1.12598L6.75233 1.27284C6.71467 1.18246 6.63182 1.12598 6.53391 1.12598Z" fill="#464647"/>
|
|
6
|
+
<path d="M7.99449 1.12598H7.22627L6.87982 1.35946H6.53334H6.29987V1.7511C6.29987 1.87914 6.40531 1.98458 6.53334 1.98458C6.56724 1.98458 6.59736 1.97705 6.62749 1.96575C6.66891 1.95822 6.82333 1.94316 7.27899 1.94316C7.7083 1.94316 7.85515 1.95822 7.89657 1.96575C8.01331 2.01847 8.15265 1.96575 8.20914 1.84901C8.2242 1.81889 8.23173 1.785 8.23173 1.7511V1.35946C8.23173 1.23142 8.12629 1.12598 7.99825 1.12598H7.99449ZM6.74423 1.85278C6.74423 1.85278 6.75931 1.82265 6.76308 1.80383C6.75931 1.81889 6.75176 1.83771 6.74423 1.85278ZM6.76308 1.80383C6.76308 1.80383 6.76306 1.78876 6.76682 1.77746C6.76682 1.78499 6.76684 1.79629 6.76308 1.80383ZM7.76854 1.80383C7.76854 1.80383 7.77607 1.83771 7.7836 1.85278C7.77607 1.83771 7.77231 1.82265 7.76854 1.80383ZM7.76478 1.77746C7.76478 1.77746 7.76478 1.79252 7.76854 1.80006C7.76854 1.79252 7.76854 1.78499 7.76478 1.77746Z" fill="#464647"/>
|
|
7
|
+
<path d="M7.99439 1.46867H6.53324C6.12654 1.46867 5.79891 1.13351 5.80267 0.73057C5.80267 0.331393 6.13407 0.00376582 6.53324 0H7.99815C8.19398 0 8.3785 0.0790829 8.51784 0.218418C8.65717 0.357754 8.72872 0.542281 8.72872 0.738103C8.72872 1.13728 8.39733 1.46491 7.99815 1.46867H7.99439ZM7.99439 0.474497H6.53324C6.39391 0.474497 6.27717 0.591235 6.27717 0.73057C6.27717 0.873671 6.39014 0.990413 6.53324 0.990413H7.99062C8.12995 0.990413 8.24669 0.873675 8.24669 0.73434C8.24669 0.666555 8.22035 0.598768 8.17139 0.549812C8.12243 0.500857 8.05842 0.474493 7.98687 0.470728L7.99439 0.474497Z" fill="#464647"/>
|
|
8
|
+
<path d="M3.63795 3.72449H1.86426C1.73246 3.72449 1.62701 3.61905 1.62701 3.48725C1.62701 3.35544 1.73246 3.25 1.86426 3.25H3.63795C3.76975 3.25 3.8752 3.35544 3.8752 3.48725C3.8752 3.61905 3.76975 3.72449 3.63795 3.72449Z" fill="#464647"/>
|
|
9
|
+
<path d="M2.67736 6.5487H1.45347C1.32166 6.5487 1.21622 6.44326 1.21622 6.31146C1.21622 6.17965 1.32166 6.07422 1.45347 6.07422H2.67736C2.80916 6.07422 2.91461 6.17965 2.91461 6.31146C2.91461 6.44326 2.80916 6.5487 2.67736 6.5487Z" fill="#464647"/>
|
|
10
|
+
<path d="M2.86165 7.93493H1.20847C1.07667 7.93493 0.971222 7.8295 0.971222 7.6977C0.971222 7.56589 1.07667 7.46045 1.20847 7.46045H2.86165C2.99345 7.46045 3.0989 7.56589 3.0989 7.6977C3.0989 7.8295 2.99345 7.93493 2.86165 7.93493Z" fill="#464647"/>
|
|
11
|
+
<path d="M2.91474 5.13636H0.237249C0.105445 5.13636 0 5.03091 0 4.89911C0 4.7673 0.105445 4.66187 0.237249 4.66187H2.91474C3.04655 4.66187 3.15199 4.7673 3.15199 4.89911C3.15199 5.03091 3.04655 5.13636 2.91474 5.13636Z" fill="#464647"/>
|
|
12
|
+
<path d="M7.09121 6.21729C7.03096 6.21729 6.97071 6.19469 6.92552 6.1495L5.97652 5.21558C5.88238 5.1252 5.88238 4.97457 5.97652 4.88042C6.0669 4.78628 6.21754 4.78628 6.31169 4.88042L7.26066 5.81435C7.3548 5.90473 7.3548 6.05536 7.26066 6.1495C7.21547 6.19846 7.15147 6.22105 7.09121 6.22105V6.21729Z" fill="#464647"/>
|
|
13
|
+
<path d="M7.51304 6.28133C7.45279 6.28133 7.39253 6.25874 7.34734 6.21355C7.2532 6.1194 7.2532 5.97253 7.34734 5.87838L8.9591 4.25909C9.05325 4.16494 9.20012 4.16494 9.29427 4.25909C9.38841 4.35323 9.38841 4.5001 9.29427 4.59424L7.68248 6.21355C7.63729 6.25874 7.57706 6.2851 7.51304 6.2851V6.28133Z" fill="#464647"/>
|
|
14
|
+
</svg>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { FilterSortBarColors, FilterSortBarIcons } from "./types";
|
|
2
|
+
import { FilterSortBarColors, FilterSortBarIcons, SortDirection } from "./types";
|
|
3
3
|
interface FilterChipProps {
|
|
4
4
|
label: string;
|
|
5
5
|
active: boolean;
|
|
@@ -14,8 +14,12 @@ interface FilterChipProps {
|
|
|
14
14
|
badgeCount?: number;
|
|
15
15
|
/** When true, the label text is hidden and only the icon + badge + chevron show (used for the Filtros button once the strip is scrolled). */
|
|
16
16
|
collapsed?: boolean;
|
|
17
|
+
/** Renders a directional arrow instead of the dropdown chevron — used for base sort chips (Horario, Precio, Rápido). */
|
|
18
|
+
sortDirection?: SortDirection;
|
|
19
|
+
/** Suppresses the trailing chevron/arrow entirely — used for cohort sort chips (Después de las 6 PM, Salón Cama), which just toggle on/off. */
|
|
20
|
+
hideTrailingIcon?: boolean;
|
|
17
21
|
colors: Required<Pick<FilterSortBarColors, "primaryColor" | "primaryTextColor" | "chipBorderColor" | "chipTextColor" | "badgeBackgroundColor" | "badgeTextColor">>;
|
|
18
22
|
icons?: FilterSortBarIcons;
|
|
19
23
|
}
|
|
20
|
-
declare const FilterChip: ({ label, active, isOpen, onClick, isFiltersButton, iconSrc, activeIconSrc, badgeCount, collapsed, colors, icons, }: FilterChipProps) => React.JSX.Element;
|
|
24
|
+
declare const FilterChip: ({ label, active, isOpen, onClick, isFiltersButton, iconSrc, activeIconSrc, badgeCount, collapsed, sortDirection, hideTrailingIcon, colors, icons, }: FilterChipProps) => React.JSX.Element;
|
|
21
25
|
export default FilterChip;
|
|
@@ -1,42 +1,20 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { ChevronDownIcon, FilterIcon } from "./icons";
|
|
3
|
-
const FilterChip = ({ label, active, isOpen, onClick, isFiltersButton, iconSrc, activeIconSrc, badgeCount = 0, collapsed, colors, icons, }) => {
|
|
2
|
+
import { ChevronDownIcon, FilterIcon, SortArrowIcon } from "./icons";
|
|
3
|
+
const FilterChip = ({ label, active, isOpen, onClick, isFiltersButton, iconSrc, activeIconSrc, badgeCount = 0, collapsed, sortDirection, hideTrailingIcon, colors, icons, }) => {
|
|
4
4
|
const isHighlighted = active || isOpen;
|
|
5
|
-
return (React.createElement("button", { onClick: onClick, style: {
|
|
6
|
-
flexShrink: 0,
|
|
7
|
-
display: "flex",
|
|
8
|
-
alignItems: "center",
|
|
9
|
-
gap: 6,
|
|
10
|
-
padding: "9px 14px",
|
|
11
|
-
borderRadius: 20,
|
|
5
|
+
return (React.createElement("button", { onClick: onClick, className: "flex flex-shrink-0 items-center gap-[6px] px-[14px] py-[9px] rounded-[20px] text-[13px] font-medium whitespace-nowrap cursor-pointer transition-[padding] duration-200 ease-in-out [-webkit-tap-highlight-color:transparent]", style: {
|
|
12
6
|
border: `1px solid ${isHighlighted ? colors.primaryColor : colors.chipBorderColor}`,
|
|
13
7
|
backgroundColor: isHighlighted ? colors.primaryColor : "#fff",
|
|
14
8
|
color: isHighlighted ? colors.primaryTextColor : colors.chipTextColor,
|
|
15
|
-
fontSize: 13,
|
|
16
|
-
fontWeight: 500,
|
|
17
|
-
whiteSpace: "nowrap",
|
|
18
|
-
cursor: "pointer",
|
|
19
|
-
transition: "padding 0.2s ease",
|
|
20
|
-
WebkitTapHighlightColor: "transparent",
|
|
21
9
|
} },
|
|
22
10
|
isFiltersButton && (React.createElement(FilterIcon, { size: 14, color: isHighlighted ? colors.primaryTextColor : colors.chipTextColor, src: icons === null || icons === void 0 ? void 0 : icons.filterIcon, active: isHighlighted })),
|
|
23
|
-
!isFiltersButton && iconSrc && (React.createElement("img", { src: isHighlighted && activeIconSrc ? activeIconSrc : iconSrc, width: 14, height: 14, alt: "",
|
|
24
|
-
badgeCount > 0 && (React.createElement("span", { style: {
|
|
25
|
-
display: "inline-flex",
|
|
26
|
-
flexShrink: 0,
|
|
27
|
-
alignItems: "center",
|
|
28
|
-
justifyContent: "center",
|
|
29
|
-
width: 16,
|
|
30
|
-
height: 16,
|
|
31
|
-
borderRadius: "50%",
|
|
32
|
-
boxSizing: "border-box",
|
|
33
|
-
fontSize: 10,
|
|
34
|
-
fontWeight: 700,
|
|
35
|
-
lineHeight: 1,
|
|
36
|
-
backgroundColor: colors.badgeBackgroundColor,
|
|
37
|
-
color: colors.badgeTextColor,
|
|
38
|
-
} }, badgeCount)),
|
|
11
|
+
!isFiltersButton && iconSrc && (React.createElement("img", { src: isHighlighted && activeIconSrc ? activeIconSrc : iconSrc, width: 14, height: 14, alt: "", className: isHighlighted && !activeIconSrc ? "brightness-0 invert" : undefined })),
|
|
39
12
|
!collapsed && React.createElement("span", null, label),
|
|
40
|
-
React.createElement(
|
|
13
|
+
badgeCount > 0 && (React.createElement("span", { className: "inline-flex flex-shrink-0 items-center justify-center w-[18px] h-[18px] rounded-full box-border text-[10px] font-bold leading-none", style: {
|
|
14
|
+
backgroundColor: !isFiltersButton && isHighlighted ? "#FFFFFF" : colors.badgeBackgroundColor,
|
|
15
|
+
color: !isFiltersButton && isHighlighted ? colors.primaryColor : colors.badgeTextColor,
|
|
16
|
+
} }, badgeCount)),
|
|
17
|
+
!hideTrailingIcon &&
|
|
18
|
+
(sortDirection ? (React.createElement(SortArrowIcon, { size: 9, color: isHighlighted ? colors.primaryTextColor : colors.chipTextColor, direction: sortDirection, src: icons === null || icons === void 0 ? void 0 : icons.sortArrowIcon, active: isHighlighted })) : (React.createElement(ChevronDownIcon, { size: 8, color: isHighlighted ? colors.primaryTextColor : colors.chipTextColor, open: isOpen, src: icons === null || icons === void 0 ? void 0 : icons.chevronDownIcon })))));
|
|
41
19
|
};
|
|
42
20
|
export default FilterChip;
|
|
@@ -6,5 +6,5 @@ import { FilterSortBarMobileProps } from "./types";
|
|
|
6
6
|
* consumer's list — sees a change until Aplicar commits the draft via
|
|
7
7
|
* onApply. Closing the sheet without applying discards it.
|
|
8
8
|
*/
|
|
9
|
-
declare const FilterSortBarMobile: ({ categories, onApply, onClearFilter, currencySign, colors, icons, }: FilterSortBarMobileProps) => React.JSX.Element;
|
|
9
|
+
declare const FilterSortBarMobile: ({ categories, onApply, onClearFilter, sortOptions, onSortChange, currencySign, colors, icons, }: FilterSortBarMobileProps) => React.JSX.Element;
|
|
10
10
|
export default FilterSortBarMobile;
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from "react";
|
|
2
2
|
import FilterChip from "./FilterChip";
|
|
3
|
-
import SingleFilterSheet from "./SingleFilterSheet";
|
|
4
3
|
import FiltersMasterSheet from "./FiltersMasterSheet";
|
|
5
4
|
import { DEFAULT_ICONS } from "./defaultIcons";
|
|
5
|
+
// Sort chips reuse an existing category or time-of-day icon where the
|
|
6
|
+
// concept already has one (Horario→clock, Empresas→bus, Precio→piggy bank,
|
|
7
|
+
// Después de las 6 PM→moon, Antes de las 6 AM→sunrise, Salón Cama→seat);
|
|
8
|
+
// only keys with no such match (e.g. "duration" for Rápido) fall back to
|
|
9
|
+
// icons.sortIcons.
|
|
10
|
+
const SORT_ICON_SOURCE = {
|
|
11
|
+
time: { category: "time" },
|
|
12
|
+
company: { category: "company" },
|
|
13
|
+
price: { category: "price" },
|
|
14
|
+
after_6pm: { timeOfDay: "night" },
|
|
15
|
+
before_6am: { timeOfDay: "sunrise" },
|
|
16
|
+
cama: { category: "seatType" },
|
|
17
|
+
};
|
|
6
18
|
const DEFAULT_COLORS = {
|
|
7
19
|
primaryColor: "#FF5C60",
|
|
8
20
|
primaryTextColor: "#FFFFFF",
|
|
@@ -10,8 +22,6 @@ const DEFAULT_COLORS = {
|
|
|
10
22
|
chipTextColor: "#464647",
|
|
11
23
|
badgeBackgroundColor: "#FFCBCC",
|
|
12
24
|
badgeTextColor: "#FF5C60",
|
|
13
|
-
// Falls back to primaryColor/primaryTextColor below when the consumer
|
|
14
|
-
// doesn't pass a dedicated CTA button color.
|
|
15
25
|
buttonColor: "#FF5C60",
|
|
16
26
|
buttonTextColor: "#FFFFFF",
|
|
17
27
|
};
|
|
@@ -23,7 +33,10 @@ const getCategoryActiveCount = (category) => {
|
|
|
23
33
|
? 1
|
|
24
34
|
: 0;
|
|
25
35
|
}
|
|
26
|
-
|
|
36
|
+
// checkedViaSort options are a display mirror of an active sort chip, not
|
|
37
|
+
// a real selection — the sort chip's own active count already covers it,
|
|
38
|
+
// so counting it here too would double it.
|
|
39
|
+
return ((_a = category.options) === null || _a === void 0 ? void 0 : _a.filter((o) => o.selected && !o.checkedViaSort).length) || 0;
|
|
27
40
|
};
|
|
28
41
|
const isCategoryActive = (category) => getCategoryActiveCount(category) > 0;
|
|
29
42
|
/**
|
|
@@ -32,21 +45,34 @@ const isCategoryActive = (category) => getCategoryActiveCount(category) > 0;
|
|
|
32
45
|
* consumer's list — sees a change until Aplicar commits the draft via
|
|
33
46
|
* onApply. Closing the sheet without applying discards it.
|
|
34
47
|
*/
|
|
35
|
-
const FilterSortBarMobile = ({ categories, onApply, onClearFilter, currencySign = "$", colors, icons, }) => {
|
|
48
|
+
const FilterSortBarMobile = ({ categories, onApply, onClearFilter, sortOptions, onSortChange, currencySign = "$", colors, icons, }) => {
|
|
36
49
|
const [openSheet, setOpenSheet] = useState(null);
|
|
37
50
|
const [isScrolled, setIsScrolled] = useState(false);
|
|
38
51
|
const [draftCategories, setDraftCategories] = useState(categories);
|
|
39
52
|
const scrollRef = useRef(null);
|
|
40
53
|
const resolvedColors = Object.assign(Object.assign({}, DEFAULT_COLORS), colors);
|
|
41
|
-
const resolvedIcons = Object.assign(Object.assign(Object.assign({}, DEFAULT_ICONS), icons), { categoryIcons: Object.assign(Object.assign({}, DEFAULT_ICONS.categoryIcons), icons === null || icons === void 0 ? void 0 : icons.categoryIcons), categoryIconsActive: Object.assign(Object.assign({}, DEFAULT_ICONS.categoryIconsActive), icons === null || icons === void 0 ? void 0 : icons.categoryIconsActive), timeOfDayIcons: Object.assign(Object.assign({}, DEFAULT_ICONS.timeOfDayIcons), icons === null || icons === void 0 ? void 0 : icons.timeOfDayIcons) });
|
|
54
|
+
const resolvedIcons = Object.assign(Object.assign(Object.assign({}, DEFAULT_ICONS), icons), { categoryIcons: Object.assign(Object.assign({}, DEFAULT_ICONS.categoryIcons), icons === null || icons === void 0 ? void 0 : icons.categoryIcons), categoryIconsActive: Object.assign(Object.assign({}, DEFAULT_ICONS.categoryIconsActive), icons === null || icons === void 0 ? void 0 : icons.categoryIconsActive), timeOfDayIcons: Object.assign(Object.assign({}, DEFAULT_ICONS.timeOfDayIcons), icons === null || icons === void 0 ? void 0 : icons.timeOfDayIcons), sortIcons: Object.assign(Object.assign({}, DEFAULT_ICONS.sortIcons), icons === null || icons === void 0 ? void 0 : icons.sortIcons) });
|
|
55
|
+
const resolveSortIcon = (key) => {
|
|
56
|
+
var _a, _b, _c;
|
|
57
|
+
const source = SORT_ICON_SOURCE[key];
|
|
58
|
+
if (source === null || source === void 0 ? void 0 : source.category)
|
|
59
|
+
return (_a = resolvedIcons.categoryIcons) === null || _a === void 0 ? void 0 : _a[source.category];
|
|
60
|
+
if (source === null || source === void 0 ? void 0 : source.timeOfDay)
|
|
61
|
+
return (_b = resolvedIcons.timeOfDayIcons) === null || _b === void 0 ? void 0 : _b[source.timeOfDay];
|
|
62
|
+
return (_c = resolvedIcons.sortIcons) === null || _c === void 0 ? void 0 : _c[key];
|
|
63
|
+
};
|
|
42
64
|
// Re-sync the draft whenever the committed categories change from the
|
|
43
65
|
// outside (a real Aplicar/Borrar filtro commit, or fresh search results).
|
|
44
66
|
useEffect(() => {
|
|
45
67
|
setDraftCategories(categories);
|
|
46
68
|
}, [categories]);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
69
|
+
// Every filter chip opens the same master sheet, pre-selecting whichever
|
|
70
|
+
// category was tapped ("all" — the Filtros button — leaves it unset so
|
|
71
|
+
// FiltersMasterSheet falls back to its first category).
|
|
72
|
+
const isMasterOpen = openSheet !== null;
|
|
73
|
+
const initialCategoryKey = openSheet && openSheet !== "all" ? openSheet : undefined;
|
|
74
|
+
const totalActiveCategories = categories.filter(isCategoryActive).length +
|
|
75
|
+
(sortOptions || []).filter((s) => !s.direction && s.active).length;
|
|
50
76
|
const handleScroll = () => {
|
|
51
77
|
var _a, _b;
|
|
52
78
|
setIsScrolled(((_b = (_a = scrollRef.current) === null || _a === void 0 ? void 0 : _a.scrollLeft) !== null && _b !== void 0 ? _b : 0) > 4);
|
|
@@ -64,15 +90,6 @@ const FilterSortBarMobile = ({ categories, onApply, onClearFilter, currencySign
|
|
|
64
90
|
setDraftCategories((prev) => prev.map((cat) => cat.key === categoryKey && cat.priceRange
|
|
65
91
|
? Object.assign(Object.assign({}, cat), { priceRange: Object.assign(Object.assign({}, cat.priceRange), { currentMin, currentMax }) }) : cat));
|
|
66
92
|
};
|
|
67
|
-
const handleApplySingle = () => {
|
|
68
|
-
if (openSheet && openSheet !== "all")
|
|
69
|
-
onApply(openSheet, draftCategories);
|
|
70
|
-
closeSheet();
|
|
71
|
-
};
|
|
72
|
-
const handleClearSingle = () => {
|
|
73
|
-
if (openSheet && openSheet !== "all")
|
|
74
|
-
onClearFilter(openSheet);
|
|
75
|
-
};
|
|
76
93
|
const handleApplyAll = () => {
|
|
77
94
|
onApply("all", draftCategories);
|
|
78
95
|
closeSheet();
|
|
@@ -87,35 +104,51 @@ const FilterSortBarMobile = ({ categories, onApply, onClearFilter, currencySign
|
|
|
87
104
|
? Object.assign(Object.assign({}, cat), { options: (cat.options || []).map((o) => o.id === optionId ? Object.assign(Object.assign({}, o), { selected: !o.selected }) : o) }) : cat);
|
|
88
105
|
onApply(categoryKey, updated);
|
|
89
106
|
};
|
|
107
|
+
// Directional sorts (Horario, Precio, Rápido) are mutually exclusive —
|
|
108
|
+
// picking one deactivates the others, and re-tapping the active one flips
|
|
109
|
+
// its direction. Cohort sorts (no `direction`, e.g. Después de las 6 PM,
|
|
110
|
+
// Salón Cama) are independent toggles that layer on top of whichever
|
|
111
|
+
// directional sort is active.
|
|
112
|
+
const handleSortChipClick = (key) => {
|
|
113
|
+
if (!sortOptions || !onSortChange)
|
|
114
|
+
return;
|
|
115
|
+
const target = sortOptions.find((s) => s.key === key);
|
|
116
|
+
if (!target)
|
|
117
|
+
return;
|
|
118
|
+
const updated = sortOptions.map((s) => {
|
|
119
|
+
if (s.direction) {
|
|
120
|
+
if (s.key !== key)
|
|
121
|
+
return s.active ? Object.assign(Object.assign({}, s), { active: false }) : s;
|
|
122
|
+
return s.active ? Object.assign(Object.assign({}, s), { direction: s.direction === "asc" ? "desc" : "asc" }) : Object.assign(Object.assign({}, s), { active: true });
|
|
123
|
+
}
|
|
124
|
+
return s.key === key ? Object.assign(Object.assign({}, s), { active: !s.active }) : s;
|
|
125
|
+
});
|
|
126
|
+
onSortChange(updated);
|
|
127
|
+
};
|
|
90
128
|
return (React.createElement("div", null,
|
|
91
|
-
React.createElement("div", {
|
|
129
|
+
React.createElement("div", { className: "flex items-center gap-[8px]" },
|
|
92
130
|
React.createElement(FilterChip, { label: "Filtros", active: totalActiveCategories > 0, isOpen: isMasterOpen, onClick: () => openSheetFor("all"), isFiltersButton: true, badgeCount: totalActiveCategories, collapsed: isScrolled, colors: resolvedColors, icons: resolvedIcons }),
|
|
93
|
-
React.createElement("div", { style: {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
gap: 8,
|
|
104
|
-
overflowX: "auto",
|
|
105
|
-
scrollbarWidth: "none",
|
|
106
|
-
paddingBottom: 2,
|
|
107
|
-
} },
|
|
108
|
-
categories.map((category) => {
|
|
131
|
+
React.createElement("div", { className: "w-px self-stretch flex-shrink-0 opacity-50", style: { backgroundColor: resolvedColors.chipBorderColor } }),
|
|
132
|
+
React.createElement("div", { ref: scrollRef, onScroll: handleScroll, className: "flex items-center gap-[8px] overflow-x-auto pb-[2px] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden" }, sortOptions === null || sortOptions === void 0 ? void 0 :
|
|
133
|
+
sortOptions.map((sort) => (React.createElement(FilterChip, { key: `sort:${sort.key}`, label: sort.label, active: sort.active, isOpen: false, onClick: () => handleSortChipClick(sort.key), iconSrc: resolveSortIcon(sort.key), sortDirection: sort.direction && sort.active ? sort.direction : undefined, hideTrailingIcon: !(sort.direction && sort.active), badgeCount: sort.active ? sort.count : undefined, colors: resolvedColors, icons: resolvedIcons }))),
|
|
134
|
+
categories
|
|
135
|
+
// hideChip categories never get a standalone top-bar chip, even
|
|
136
|
+
// once something is selected inside the Filtros sheet — surfacing
|
|
137
|
+
// it there duplicated the dedicated sort chip for the same
|
|
138
|
+
// concept (e.g. "Horarios" filter next to the "Horario" sort chip).
|
|
139
|
+
.filter((category) => !category.hideChip)
|
|
140
|
+
.map((category) => {
|
|
109
141
|
var _a, _b;
|
|
110
142
|
return (React.createElement(FilterChip, { key: category.key, label: category.label, active: isCategoryActive(category), isOpen: openSheet === category.key, onClick: () => openSheetFor(category.key), iconSrc: (_a = resolvedIcons.categoryIcons) === null || _a === void 0 ? void 0 : _a[category.key], activeIconSrc: (_b = resolvedIcons.categoryIconsActive) === null || _b === void 0 ? void 0 : _b[category.key], badgeCount: getCategoryActiveCount(category), colors: resolvedColors, icons: resolvedIcons }));
|
|
111
143
|
}),
|
|
112
144
|
categories
|
|
113
145
|
.filter((category) => { var _a; return category.inlineOptions && ((_a = category.options) === null || _a === void 0 ? void 0 : _a.length); })
|
|
114
|
-
.flatMap((category) => (category.options || [])
|
|
146
|
+
.flatMap((category) => (category.options || [])
|
|
147
|
+
.filter((option) => !option.excludeFromInline)
|
|
148
|
+
.map((option) => {
|
|
115
149
|
var _a;
|
|
116
150
|
return (React.createElement(FilterChip, { key: `${category.key}:${option.id}`, label: option.label, active: option.selected, isOpen: false, onClick: () => handleInlineOptionToggle(category.key, option.id), iconSrc: option.icon ? (_a = resolvedIcons.timeOfDayIcons) === null || _a === void 0 ? void 0 : _a[option.icon] : undefined, colors: resolvedColors, icons: resolvedIcons }));
|
|
117
151
|
})))),
|
|
118
|
-
React.createElement(
|
|
119
|
-
React.createElement(FiltersMasterSheet, { isOpen: isMasterOpen, categories: draftCategories, onClose: closeSheet, onToggleOption: handleDraftToggleOption, onPriceRangeChange: handleDraftPriceRangeChange, onClearAll: handleClearAll, onApplyAll: handleApplyAll, currencySign: currencySign, colors: resolvedColors, icons: resolvedIcons })));
|
|
152
|
+
React.createElement(FiltersMasterSheet, { isOpen: isMasterOpen, initialCategoryKey: initialCategoryKey, categories: draftCategories, onClose: closeSheet, onToggleOption: handleDraftToggleOption, onPriceRangeChange: handleDraftPriceRangeChange, onClearAll: handleClearAll, onApplyAll: handleApplyAll, currencySign: currencySign, colors: resolvedColors, icons: resolvedIcons })));
|
|
120
153
|
};
|
|
121
154
|
export default FilterSortBarMobile;
|
|
@@ -2,6 +2,8 @@ import React from "react";
|
|
|
2
2
|
import { FilterCategory, FilterCategoryKey, FilterSortBarColors, FilterSortBarIcons } from "./types";
|
|
3
3
|
interface FiltersMasterSheetProps {
|
|
4
4
|
isOpen: boolean;
|
|
5
|
+
/** Category to pre-select when the sheet opens — set when a specific filter chip (rather than the Filtros button) was tapped. */
|
|
6
|
+
initialCategoryKey?: FilterCategoryKey;
|
|
5
7
|
categories: FilterCategory[];
|
|
6
8
|
onClose: () => void;
|
|
7
9
|
onToggleOption: (categoryKey: FilterCategoryKey, optionId: string) => void;
|
|
@@ -12,5 +14,5 @@ interface FiltersMasterSheetProps {
|
|
|
12
14
|
colors: Required<FilterSortBarColors>;
|
|
13
15
|
icons?: FilterSortBarIcons;
|
|
14
16
|
}
|
|
15
|
-
declare const FiltersMasterSheet: ({ isOpen, categories, onClose, onToggleOption, onPriceRangeChange, onClearAll, onApplyAll, currencySign, colors, icons, }: FiltersMasterSheetProps) => React.JSX.Element;
|
|
17
|
+
declare const FiltersMasterSheet: ({ isOpen, initialCategoryKey, categories, onClose, onToggleOption, onPriceRangeChange, onClearAll, onApplyAll, currencySign, colors, icons, }: FiltersMasterSheetProps) => React.JSX.Element;
|
|
16
18
|
export default FiltersMasterSheet;
|
|
@@ -1,111 +1,42 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
2
|
import { BottomSheet } from "../../ui/BottomSheet";
|
|
3
|
-
import { CloseIcon
|
|
3
|
+
import { CloseIcon } from "./icons";
|
|
4
4
|
import OptionCheckboxList from "./OptionCheckboxList";
|
|
5
5
|
import PriceRangeSlider from "./PriceRangeSlider";
|
|
6
6
|
import SheetFooter from "./SheetFooter";
|
|
7
|
-
const FiltersMasterSheet = ({ isOpen, categories, onClose, onToggleOption, onPriceRangeChange, onClearAll, onApplyAll, currencySign, colors, icons, }) => {
|
|
7
|
+
const FiltersMasterSheet = ({ isOpen, initialCategoryKey, categories, onClose, onToggleOption, onPriceRangeChange, onClearAll, onApplyAll, currencySign, colors, icons, }) => {
|
|
8
8
|
var _a, _b;
|
|
9
|
-
const [activeKey, setActiveKey] = useState((_b = (_a = categories[0]) === null || _a === void 0 ? void 0 : _a.key) !== null && _b !== void 0 ? _b : "time");
|
|
10
|
-
|
|
9
|
+
const [activeKey, setActiveKey] = useState((_b = initialCategoryKey !== null && initialCategoryKey !== void 0 ? initialCategoryKey : (_a = categories[0]) === null || _a === void 0 ? void 0 : _a.key) !== null && _b !== void 0 ? _b : "time");
|
|
10
|
+
// Reset the pre-selected tab every time the sheet is (re)opened, whether
|
|
11
|
+
// via a specific filter chip or the general Filtros button.
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
var _a, _b;
|
|
14
|
+
if (isOpen) {
|
|
15
|
+
setActiveKey((_b = initialCategoryKey !== null && initialCategoryKey !== void 0 ? initialCategoryKey : (_a = categories[0]) === null || _a === void 0 ? void 0 : _a.key) !== null && _b !== void 0 ? _b : "time");
|
|
16
|
+
}
|
|
17
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
18
|
+
}, [isOpen]);
|
|
11
19
|
const activeCategory = categories.find((c) => c.key === activeKey) || categories[0];
|
|
12
|
-
const filteredOptions = useMemo(() => {
|
|
13
|
-
if (!(activeCategory === null || activeCategory === void 0 ? void 0 : activeCategory.options))
|
|
14
|
-
return [];
|
|
15
|
-
if (!searchQuery.trim())
|
|
16
|
-
return activeCategory.options;
|
|
17
|
-
const q = searchQuery.trim().toLowerCase();
|
|
18
|
-
return activeCategory.options.filter((o) => o.label.toLowerCase().includes(q));
|
|
19
|
-
}, [activeCategory, searchQuery]);
|
|
20
20
|
if (!isOpen)
|
|
21
21
|
return null;
|
|
22
|
-
return (React.createElement(BottomSheet, { isOpen: isOpen, onClose: onClose, showBackdrop: true, height: "
|
|
23
|
-
React.createElement("div", {
|
|
24
|
-
React.createElement("div", {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
React.createElement("
|
|
31
|
-
React.createElement("div", { onClick: onClose, style: { cursor: "pointer", padding: 4, WebkitTapHighlightColor: "transparent" } },
|
|
32
|
-
React.createElement(CloseIcon, { size: 14, src: icons === null || icons === void 0 ? void 0 : icons.closeIcon }))),
|
|
33
|
-
React.createElement("div", { style: { padding: "0 20px 14px" } },
|
|
34
|
-
React.createElement("div", { style: {
|
|
35
|
-
display: "flex",
|
|
36
|
-
alignItems: "center",
|
|
37
|
-
gap: 8,
|
|
38
|
-
border: "1px solid #E5E5E5",
|
|
39
|
-
borderRadius: 10,
|
|
40
|
-
padding: "9px 12px",
|
|
41
|
-
} },
|
|
42
|
-
React.createElement(SearchIcon, { size: 15, src: icons === null || icons === void 0 ? void 0 : icons.searchIcon }),
|
|
43
|
-
React.createElement("input", { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: "Buscar filtro", style: {
|
|
44
|
-
border: "none",
|
|
45
|
-
outline: "none",
|
|
46
|
-
fontSize: 13,
|
|
47
|
-
flex: 1,
|
|
48
|
-
color: "#464647",
|
|
49
|
-
background: "transparent",
|
|
50
|
-
} }))),
|
|
51
|
-
React.createElement("div", { style: { display: "flex", flex: 1, overflow: "hidden", position: "relative", borderTop: "1px solid #E5E5E5", borderBottom: "1px solid #E5E5E5" } },
|
|
52
|
-
React.createElement("div", { style: {
|
|
53
|
-
position: "absolute",
|
|
54
|
-
top: 0,
|
|
55
|
-
bottom: 0,
|
|
56
|
-
left: 0,
|
|
57
|
-
width: 130,
|
|
58
|
-
backgroundColor: "#F3F4F6",
|
|
59
|
-
zIndex: 0,
|
|
60
|
-
} }),
|
|
61
|
-
React.createElement("div", { style: {
|
|
62
|
-
width: 130,
|
|
63
|
-
flexShrink: 0,
|
|
64
|
-
position: "relative",
|
|
65
|
-
zIndex: 1,
|
|
66
|
-
} }, categories.map((cat) => {
|
|
22
|
+
return (React.createElement(BottomSheet, { isOpen: isOpen, onClose: onClose, showBackdrop: true, height: "65vh", padding: "20px 0 0px" },
|
|
23
|
+
React.createElement("div", { className: "flex flex-col h-[calc(65vh-40px)]" },
|
|
24
|
+
React.createElement("div", { className: "flex items-center justify-between px-[20px] pb-[14px]" },
|
|
25
|
+
React.createElement("span", { className: "text-[16px] font-bold text-[#464647] font-['DMSans-Bold',sans-serif]" }, "Filtros"),
|
|
26
|
+
React.createElement("div", { onClick: onClose, className: "cursor-pointer p-[4px] [-webkit-tap-highlight-color:transparent]" },
|
|
27
|
+
React.createElement(CloseIcon, { size: 22, src: icons === null || icons === void 0 ? void 0 : icons.closeIcon }))),
|
|
28
|
+
React.createElement("div", { className: "flex flex-1 overflow-hidden relative border-t border-b border-[#E5E5E5]" },
|
|
29
|
+
React.createElement("div", { className: "absolute top-0 bottom-0 left-0 w-[120px] bg-[#F9FAFB] z-0" }),
|
|
30
|
+
React.createElement("div", { className: "w-[120px] flex-shrink-0 relative z-[1] bg-[#F9FAFB]" }, categories.map((cat) => {
|
|
67
31
|
const isActive = cat.key === activeKey;
|
|
68
|
-
return (React.createElement("div", { key: cat.key, onClick: () => setActiveKey(cat.key), style: {
|
|
69
|
-
|
|
70
|
-
display: "flex",
|
|
71
|
-
alignItems: "center",
|
|
72
|
-
minHeight: 44,
|
|
73
|
-
boxSizing: "border-box",
|
|
74
|
-
padding: "8px 8px 8px 20px",
|
|
75
|
-
fontSize: 13,
|
|
76
|
-
lineHeight: 1.25,
|
|
77
|
-
fontWeight: isActive ? 700 : 400,
|
|
78
|
-
color: isActive ? colors.primaryColor : "#464647",
|
|
79
|
-
backgroundColor: isActive ? "#fff" : "transparent",
|
|
80
|
-
cursor: "pointer",
|
|
81
|
-
WebkitTapHighlightColor: "transparent",
|
|
82
|
-
userSelect: "none",
|
|
83
|
-
WebkitUserSelect: "none",
|
|
84
|
-
} },
|
|
85
|
-
isActive && (React.createElement("div", { style: {
|
|
86
|
-
position: "absolute",
|
|
87
|
-
left: 0,
|
|
88
|
-
top: 8,
|
|
89
|
-
bottom: 8,
|
|
90
|
-
width: 4,
|
|
91
|
-
borderTopRightRadius: 4,
|
|
92
|
-
borderBottomRightRadius: 4,
|
|
93
|
-
backgroundColor: colors.primaryColor,
|
|
94
|
-
} })),
|
|
32
|
+
return (React.createElement("div", { key: cat.key, onClick: () => setActiveKey(cat.key), className: `relative flex items-center min-h-[44px] box-border py-[8px] pr-[8px] pl-[20px] text-[13px] leading-[1.25] cursor-pointer select-none [-webkit-tap-highlight-color:transparent] ${isActive ? "font-bold bg-[#FFFFFF]" : "font-normal bg-transparent"}`, style: { color: isActive ? colors.primaryColor : "#464647" } },
|
|
33
|
+
isActive && (React.createElement("div", { className: "absolute left-[0px] top-[8px] bottom-[8px] w-[4px] rounded-tr-[4px] rounded-br-[4px]", style: { backgroundColor: colors.primaryColor } })),
|
|
95
34
|
cat.label));
|
|
96
35
|
})),
|
|
97
|
-
React.createElement("div", {
|
|
98
|
-
activeCategory && (React.createElement("div", {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
color: "#9B9B9B",
|
|
102
|
-
textTransform: "uppercase",
|
|
103
|
-
letterSpacing: 0.4,
|
|
104
|
-
marginBottom: 5,
|
|
105
|
-
marginTop: 15,
|
|
106
|
-
} }, activeCategory.sectionLabel || activeCategory.label)),
|
|
107
|
-
(activeCategory === null || activeCategory === void 0 ? void 0 : activeCategory.kind) === "price" && activeCategory.priceRange ? (React.createElement(PriceRangeSlider, { value: activeCategory.priceRange, onChange: (min, max) => onPriceRangeChange(activeCategory.key, min, max), currencySign: currencySign, primaryColor: colors.primaryColor, minLabel: "M\u00EDnimo", maxLabel: "M\u00E1ximo" })) : (React.createElement(OptionCheckboxList, { options: filteredOptions, kind: (activeCategory === null || activeCategory === void 0 ? void 0 : activeCategory.kind) || "checkbox", onToggle: (optionId) => onToggleOption(activeCategory.key, optionId), primaryColor: colors.primaryColor, starColor: colors.buttonColor || colors.primaryColor, icons: icons })))),
|
|
108
|
-
React.createElement("div", { style: { padding: "0px 20px 0" } },
|
|
36
|
+
React.createElement("div", { className: "flex-1 overflow-y-auto pl-[16px] pr-[20px] relative z-[1] bg-white" },
|
|
37
|
+
activeCategory && (React.createElement("div", { className: "text-[11px] font-bold text-[#9B9B9B] uppercase tracking-[0.4px] mb-[5px] mt-[15px]" }, activeCategory.sectionLabel || activeCategory.label)),
|
|
38
|
+
(activeCategory === null || activeCategory === void 0 ? void 0 : activeCategory.kind) === "price" && activeCategory.priceRange ? (React.createElement(PriceRangeSlider, { value: activeCategory.priceRange, onChange: (min, max) => onPriceRangeChange(activeCategory.key, min, max), currencySign: currencySign, primaryColor: colors.primaryColor, minLabel: "M\u00EDnimo", maxLabel: "M\u00E1ximo" })) : (React.createElement(OptionCheckboxList, { options: (activeCategory === null || activeCategory === void 0 ? void 0 : activeCategory.options) || [], kind: (activeCategory === null || activeCategory === void 0 ? void 0 : activeCategory.kind) || "checkbox", onToggle: (optionId) => onToggleOption(activeCategory.key, optionId), primaryColor: colors.primaryColor, starColor: colors.buttonColor || colors.primaryColor, icons: icons })))),
|
|
39
|
+
React.createElement("div", { className: "px-[20px]" },
|
|
109
40
|
React.createElement(SheetFooter, { onClear: onClearAll, onApply: onApplyAll, colors: colors })))));
|
|
110
41
|
};
|
|
111
42
|
export default FiltersMasterSheet;
|
|
@@ -1,27 +1,16 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { CheckboxIcon, StarIcon, TimeOfDayIcon } from "./icons";
|
|
3
|
-
const RatingLabel = ({ stars, label, starColor, icons, }) => (React.createElement("div", {
|
|
3
|
+
const RatingLabel = ({ stars, label, starColor, icons, }) => (React.createElement("div", { className: "flex items-center gap-[1px] whitespace-nowrap" },
|
|
4
4
|
Array.from({ length: 5 }, (_, i) => (React.createElement(StarIcon, { key: i, size: 10, filled: stars != null && i < stars, color: starColor, filledSrc: icons === null || icons === void 0 ? void 0 : icons.starFilledIcon, emptySrc: icons === null || icons === void 0 ? void 0 : icons.starEmptyIcon }))),
|
|
5
|
-
React.createElement("span", {
|
|
5
|
+
React.createElement("span", { className: "ml-[6px]" }, label)));
|
|
6
6
|
const OptionCheckboxList = ({ options, kind, onToggle, primaryColor, starColor, icons }) => {
|
|
7
7
|
if (!(options === null || options === void 0 ? void 0 : options.length)) {
|
|
8
|
-
return (React.createElement("div", {
|
|
8
|
+
return (React.createElement("div", { className: "py-[24px] text-center text-[#9B9B9B] text-[13px]" }, "No hay opciones disponibles"));
|
|
9
9
|
}
|
|
10
10
|
return (React.createElement("div", null, options.map((option) => {
|
|
11
11
|
var _a;
|
|
12
|
-
return (React.createElement("div", { key: option.id, onClick: () => onToggle(option.id),
|
|
13
|
-
|
|
14
|
-
alignItems: "center",
|
|
15
|
-
justifyContent: "space-between",
|
|
16
|
-
padding: "12px 2px",
|
|
17
|
-
cursor: "pointer",
|
|
18
|
-
fontSize: 13,
|
|
19
|
-
color: "#464647",
|
|
20
|
-
WebkitTapHighlightColor: "transparent",
|
|
21
|
-
userSelect: "none",
|
|
22
|
-
WebkitUserSelect: "none",
|
|
23
|
-
} },
|
|
24
|
-
kind === "rating" ? (React.createElement(RatingLabel, { stars: option.stars, label: option.label, starColor: starColor, icons: icons })) : option.icon ? (React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 10 } },
|
|
12
|
+
return (React.createElement("div", { key: option.id, onClick: () => onToggle(option.id), className: "flex items-center justify-between py-[12px] px-[2px] cursor-pointer text-[13px] text-[#464647] select-none [-webkit-tap-highlight-color:transparent]" },
|
|
13
|
+
kind === "rating" ? (React.createElement(RatingLabel, { stars: option.stars, label: option.label, starColor: starColor, icons: icons })) : option.icon ? (React.createElement("div", { className: "flex items-center gap-[10px]" },
|
|
25
14
|
React.createElement(TimeOfDayIcon, { variant: option.icon, size: 16, src: (_a = icons === null || icons === void 0 ? void 0 : icons.timeOfDayIcons) === null || _a === void 0 ? void 0 : _a[option.icon] }),
|
|
26
15
|
React.createElement("span", null, option.label))) : (React.createElement("span", null, option.label)),
|
|
27
16
|
React.createElement(CheckboxIcon, { checked: option.selected, color: primaryColor, spriteSrc: icons === null || icons === void 0 ? void 0 : icons.checkBoxIcon })));
|
|
@@ -40,73 +40,35 @@ const PriceRangeSlider = ({ value, onChange, currencySign, primaryColor, minLabe
|
|
|
40
40
|
window.addEventListener("pointermove", handlePointerMove);
|
|
41
41
|
window.addEventListener("pointerup", stopDragging);
|
|
42
42
|
};
|
|
43
|
-
return (React.createElement("div", {
|
|
44
|
-
React.createElement("div", {
|
|
45
|
-
React.createElement("div", {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
React.createElement("div", {
|
|
52
|
-
|
|
53
|
-
React.createElement("
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
padding: "6px 10px 8px",
|
|
59
|
-
} },
|
|
60
|
-
React.createElement("div", { style: { fontSize: 11, color: "#9B9B9B", marginBottom: 2 } }, maxLabel),
|
|
61
|
-
React.createElement("div", { style: { fontSize: 13, fontWeight: 700, color: "#464647" } }, formatCurrency(currentMax, currencySign)))),
|
|
62
|
-
React.createElement("div", { style: { padding: `0 ${THUMB_RADIUS}px`, overflow: "visible" } },
|
|
63
|
-
React.createElement("div", { ref: trackRef, style: {
|
|
64
|
-
position: "relative",
|
|
65
|
-
height: THUMB_SIZE,
|
|
66
|
-
display: "flex",
|
|
67
|
-
alignItems: "center",
|
|
68
|
-
touchAction: "none",
|
|
69
|
-
overflow: "visible",
|
|
70
|
-
} },
|
|
71
|
-
React.createElement("div", { style: {
|
|
72
|
-
position: "absolute",
|
|
73
|
-
left: 0,
|
|
74
|
-
right: 0,
|
|
75
|
-
height: 3,
|
|
76
|
-
borderRadius: 2,
|
|
77
|
-
backgroundColor: "#E5E5E5",
|
|
78
|
-
} }),
|
|
79
|
-
React.createElement("div", { style: {
|
|
80
|
-
position: "absolute",
|
|
81
|
-
left: `${minPct}%`,
|
|
82
|
-
right: `${100 - maxPct}%`,
|
|
83
|
-
height: 3,
|
|
84
|
-
borderRadius: 2,
|
|
43
|
+
return (React.createElement("div", { className: "p-[8px_4px_4px]" },
|
|
44
|
+
React.createElement("div", { className: "flex items-center gap-[8px] mb-[28px]" },
|
|
45
|
+
React.createElement("div", { className: "flex-1 border border-[#E5E5E5] rounded-[8px] p-[6px_10px_8px]" },
|
|
46
|
+
React.createElement("div", { className: "text-[11px] text-[#464647] mb-[2px]" }, minLabel),
|
|
47
|
+
React.createElement("div", { className: "text-[13px] font-bold text-[#464647]" }, formatCurrency(currentMin, currencySign))),
|
|
48
|
+
React.createElement("span", { className: "text-[#9B9B9B] text-[13px]" }, "-"),
|
|
49
|
+
React.createElement("div", { className: "flex-1 border border-[#E5E5E5] rounded-[8px] p-[6px_10px_8px]" },
|
|
50
|
+
React.createElement("div", { className: "text-[11px] text-[#464647] mb-[2px]" }, maxLabel),
|
|
51
|
+
React.createElement("div", { className: "text-[13px] font-bold text-[#464647]" }, formatCurrency(currentMax, currencySign)))),
|
|
52
|
+
React.createElement("div", { className: "overflow-visible", style: { padding: `0 ${THUMB_RADIUS}px` } },
|
|
53
|
+
React.createElement("div", { ref: trackRef, className: "relative flex items-center overflow-visible [touch-action:none]", style: { height: THUMB_SIZE } },
|
|
54
|
+
React.createElement("div", { className: "absolute left-0 right-0 h-[3px] rounded-[2px] bg-[#E5E5E5]" }),
|
|
55
|
+
React.createElement("div", { className: "absolute h-[3px] rounded-[2px]", style: {
|
|
56
|
+
left: `calc(${minPct}% + ${THUMB_RADIUS}px)`,
|
|
57
|
+
right: `calc(${100 - maxPct}% + ${THUMB_RADIUS}px)`,
|
|
85
58
|
backgroundColor: primaryColor,
|
|
86
59
|
} }),
|
|
87
60
|
([
|
|
88
61
|
["min", minPct, currentMin],
|
|
89
62
|
["max", maxPct, currentMax],
|
|
90
|
-
]).map(([thumb, pct]) => (React.createElement("div", { key: thumb, onPointerDown: startDragging(thumb), role: "slider", "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": thumb === "min" ? currentMin : currentMax, style: {
|
|
91
|
-
position: "absolute",
|
|
63
|
+
]).map(([thumb, pct]) => (React.createElement("div", { key: thumb, onPointerDown: startDragging(thumb), role: "slider", "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": thumb === "min" ? currentMin : currentMax, className: "absolute rounded-full bg-white cursor-grab shadow-[0_1px_4px_rgba(0,0,0,0.25)]", style: {
|
|
92
64
|
left: `${pct}%`,
|
|
93
65
|
transform: "translateX(-50%)",
|
|
94
66
|
width: THUMB_SIZE,
|
|
95
67
|
height: THUMB_SIZE,
|
|
96
|
-
borderRadius: "50%",
|
|
97
|
-
backgroundColor: "#fff",
|
|
98
68
|
border: `2px solid ${primaryColor}`,
|
|
99
|
-
boxShadow: "0 1px 4px rgba(0,0,0,0.25)",
|
|
100
|
-
cursor: "grab",
|
|
101
69
|
zIndex: thumb === "min" ? 2 : 3,
|
|
102
70
|
} }))))),
|
|
103
|
-
React.createElement("div", {
|
|
104
|
-
display: "flex",
|
|
105
|
-
justifyContent: "space-between",
|
|
106
|
-
fontSize: 11,
|
|
107
|
-
color: "#9B9B9B",
|
|
108
|
-
marginTop: 8,
|
|
109
|
-
} },
|
|
71
|
+
React.createElement("div", { className: "flex justify-between text-[11px] text-[#464647] mt-[8px]" },
|
|
110
72
|
React.createElement("span", null, formatCurrency(min, currencySign)),
|
|
111
73
|
React.createElement("span", null, formatCurrency(max, currencySign)))));
|
|
112
74
|
};
|