Commit 2cfadec3 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Merge pull request #109 from blockscout/mobile-view-navigation

mobile view navigation
parents bcc6e990 1d96aa0b
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3 16.875C3 17.496 3.504 18 4.125 18h15.75a1.125 1.125 0 0 0 0-2.25H4.125c-.621 0-1.125.504-1.125 1.125ZM3 12c0 .621.504 1.125 1.125 1.125h9.75a1.125 1.125 0 0 0 0-2.25h-9.75C3.504 10.875 3 11.379 3 12Zm1.125-3.749a1.125 1.125 0 0 1 0-2.25h12.75a1.125 1.125 0 0 1 0 2.25H4.125Z" fill="currentColor"/>
</svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.77 1H1v6.588h10.77V1ZM29 1H18.23v6.588H29V1Zm0 15.922h-6.462v5.49h-4.307V29H29V16.922Zm-21.538 0H1V29h10.77v-6.588H7.461v-5.49Z" fill="#48A9A6"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M12.461 4H4v5.176h8.461V4ZM26 4h-8.462v5.176H26V4Zm0 12.51h-5.077v4.313h-3.385V26H26V16.51Zm-16.923 0H4V26h8.461v-5.177H9.077V16.51Z" fill="#48A9A6"/>
</svg> </svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path d="M1 16.736 10 8.5m-9 8.236L11 23M1 16.736 6.283 3.528M1 16.736 8.925 27.83M10 8.5 20.547 3M10 8.5 6.283 3.528M20.547 3l2.642 11M20.547 3 29 13.566M20.547 3l-14.264.528M23.189 14v12.774m0-12.774L29 13.566m-5.811 13.208L11 23m12.189 3.774L8.925 27.83m14.264-1.056L29 13.566M11 23l-2.075 4.83m9.509-16.905h-6.868l4.226 4.226-4.226 4.755h6.868" stroke="#129C6B" stroke-width="1.4" stroke-linejoin="round"/> <path d="m4 15.793 7.071-6.472M4 15.793l7.857 4.921M4 15.793 8.15 5.415M4 15.793l6.226 8.716m.845-15.188L19.358 5m-8.287 4.321-2.92-3.906M19.358 5l2.076 8.643M19.358 5 26 13.302M19.358 5l-11.207.415m13.283 8.228v10.036m0-10.036L26 13.302m-4.566 10.377-9.577-2.965m9.577 2.965-11.208.83m11.208-.83L26 13.302m-14.143 7.412-1.63 3.795m7.471-13.283h-5.396l3.32 3.321-3.32 3.736h5.396" stroke="#129C6B" stroke-width="1.4" stroke-linejoin="round"/>
</svg> </svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<rect width="30" height="30" rx="15" fill="#328332"/> <rect x="4" y="4" width="22" height="22" rx="11" fill="#328332"/>
<path opacity=".6" d="M8.625 15.958c2.337 1.241 4.776 2.54 6.66 3.546l6.604-3.546c-2.391 3.553-4.384 6.51-6.605 9.784-2.224-3.266-4.681-6.87-6.659-9.784Zm.254-.98 6.413-3.422 6.329 3.397-6.326 3.426-6.416-3.401Zm6.405-4.518-6.659 3.506 6.63-9.708 6.634 9.73-6.605-3.528Z" fill="#fff"/> <path opacity=".6" d="M10.325 15.703c1.714.91 3.503 1.862 4.884 2.6l4.843-2.6a2325.737 2325.737 0 0 1-4.843 7.175c-1.632-2.396-3.433-5.039-4.884-7.175Zm.187-.72 4.702-2.508 4.641 2.49-4.638 2.513-4.706-2.494Zm4.697-3.313-4.884 2.571 4.863-7.119 4.864 7.135-4.843-2.586Z" fill="#fff"/>
<path opacity=".7" d="m15.284 19.504 6.605-3.546a7441.882 7441.882 0 0 1-6.605 9.784v-6.238Zm.008-7.948 6.329 3.397-6.326 3.426-.003-6.823Zm-.008-1.096-.029-6.202 6.634 9.73-6.605-3.528Z" fill="#fff"/> <path opacity=".7" d="m15.209 18.303 4.843-2.6c-1.753 2.605-4.843 7.175-4.843 7.175v-4.575Zm.005-5.829 4.641 2.492-4.638 2.512-.003-5.004Zm-.005-.803-.021-4.549 4.864 7.135-4.843-2.586Z" fill="#fff"/>
<path opacity=".7" d="m8.88 14.978 6.412.526 6.33-.548-6.326 3.426-6.417-3.404Z" fill="#fff"/> <path opacity=".7" d="m10.512 14.984 4.703.386 4.64-.402-4.638 2.512-4.705-2.496Z" fill="#fff"/>
<path d="m15.292 15.504 6.33-.548-6.326 3.426-.004-2.878Z" fill="#fff"/> <path d="m15.214 15.37 4.642-.402-4.639 2.512-.003-2.11Z" fill="#fff"/>
</svg> </svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<rect width="30" height="30" rx="15" fill="#627EEA"/> <rect x="4" y="4" width="22" height="22" rx="11" fill="#627EEA"/>
<path d="M15.305 12.153V4.088c-.013 0-.02.006-.03.012-.013.01-.028.022-.066.022-.254.497-.524.975-.799 1.462-.108.192-.218.385-.327.582-.515.9-1.03 1.834-1.544 2.768a141.5 141.5 0 0 1-.844 1.52c-.28.497-.558.994-.83 1.491-.257.468-.522.935-.787 1.402-.266.468-.531.935-.788 1.403-.048.085-.096.161-.143.238a5.99 5.99 0 0 0-.147.246h.032c.02.021.028.016.038.01.007-.005.014-.01.027-.01.112-.052.233-.112.353-.173.121-.06.242-.121.354-.173.307-.165.584-.298.86-.43l.041-.02 1.062-.52.868-.415 1.062-.519c.225-.135.47-.249.704-.358.067-.03.133-.061.197-.092.116-.053.223-.107.331-.16.101-.05.203-.101.312-.152.032 0 .064-.034.064-.069ZM15.277 25.997a.08.08 0 0 0 .029.003v-5.435c0-.035 0-.07-.033-.07a7.196 7.196 0 0 0-.257-.155c-.088-.052-.177-.104-.257-.156a93.415 93.415 0 0 0-1.499-.96 91.637 91.637 0 0 1-1.525-.979 187.64 187.64 0 0 0-1.32-.83c-.442-.277-.884-.554-1.318-.83-.017 0-.025-.01-.033-.018-.008-.009-.016-.017-.032-.017 0 .017.008.026.016.034.008.009.016.017.016.034l.483.727c.389.618.79 1.22 1.19 1.818.227.342.454.681.676 1.021l1.93 2.908c.311.469.615.93.918 1.39.324.492.648.983.98 1.483.019.02.027.029.036.032Z" fill="#fff"/> <path d="M15.224 12.912V6.998c-.01 0-.015.004-.022.009a.07.07 0 0 1-.049.016c-.186.364-.384.715-.585 1.072l-.24.426c-.378.66-.755 1.345-1.133 2.03-.202.372-.41.743-.619 1.115-.204.364-.409.73-.608 1.094a87.06 87.06 0 0 1-.578 1.028c-.194.343-.389.686-.578 1.028-.034.063-.07.119-.104.175a4.41 4.41 0 0 0-.108.18h.024c.014.016.02.013.027.007.005-.003.01-.006.02-.006a8.69 8.69 0 0 0 .26-.127c.088-.045.176-.09.259-.127.225-.121.428-.219.63-.316l.03-.014.779-.381.637-.305.778-.38c.166-.1.345-.183.517-.263l.144-.067c.085-.04.164-.079.243-.118.075-.037.149-.074.229-.111.024 0 .047-.025.047-.05ZM15.203 23.065c.005.002.011.002.021.002V19.08c0-.025 0-.051-.024-.051a5.308 5.308 0 0 0-.188-.114c-.065-.038-.13-.076-.189-.114a68.01 68.01 0 0 0-1.099-.705c-.375-.237-.75-.474-1.119-.717a140.9 140.9 0 0 0-.967-.61c-.324-.202-.649-.405-.967-.608-.012 0-.018-.007-.024-.013-.006-.006-.011-.012-.023-.012 0 .012.006.018.011.025.006.006.012.012.012.025l.354.533c.285.453.58.895.873 1.333.166.25.332.5.495.749l1.416 2.132.674 1.02c.237.36.474.72.718 1.087.014.015.02.021.026.024Z" fill="#fff"/>
<path d="M15.3 4v11.307h6.3L15.3 4ZM9 15.175l6.3-3.024v7.1L9 15.175ZM15.3 20.566v5.39l6.177-9.203-6.177 3.813Z" fill="#C0CBF6"/> <path d="M15.22 6.933v8.292h4.62l-4.62-8.292ZM10.6 15.128l4.62-2.217v5.206l-4.62-2.989ZM15.22 19.081v3.953l4.53-6.749-4.53 2.796Z" fill="#C0CBF6"/>
<path d="M15.3 19.251v-7.1l6.3 3.156-6.3 3.944Z" fill="#8197EE"/> <path d="M15.22 18.117v-5.206l4.62 2.314-4.62 2.892Z" fill="#8197EE"/>
</svg> </svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.467 7.495c.046.041.084.073.12.107.377.365.75.734 1.133 1.095.085.081.086.137.024.23-.8 1.21-1.09 2.537-.824 3.943.358 1.886 1.456 3.26 3.248 4.089 1.06.489 2.183.614 3.338.443a5.646 5.646 0 0 0 2.166-.788c.11-.068.17-.06.26.028.974.958 1.955 1.91 2.928 2.87.108.105.163.117.28.004 1.112-1.087 2.234-2.166 3.347-3.254.122-.12.199-.14.36-.047.973.568 2.033.795 3.167.744 2.25-.102 4.305-1.625 5.003-3.716.528-1.583.332-3.086-.529-4.515-.056-.093-.06-.15.025-.231.314-.293.619-.594.928-.891.028-.028.06-.052.092-.079 3.297 4.694 3.762 12.244-1.543 17.803-5.495 5.758-14.563 6.206-20.618 1.264-6.149-5.02-6.88-13.26-2.905-19.1Z" fill="#276749"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M5.809 9.496c.034.03.062.054.088.079.276.268.55.538.83.803.064.06.064.1.019.168-.587.888-.8 1.861-.605 2.892.263 1.383 1.068 2.391 2.383 2.998.776.36 1.6.451 2.447.326a4.14 4.14 0 0 0 1.588-.578c.08-.05.125-.044.19.02.715.703 1.435 1.401 2.149 2.104.078.078.12.087.204.004.816-.797 1.639-1.589 2.455-2.386.09-.088.146-.103.264-.034.713.415 1.491.582 2.322.544 1.65-.074 3.158-1.191 3.67-2.724.387-1.161.243-2.263-.388-3.311-.041-.069-.045-.11.018-.17.23-.214.454-.435.68-.653.021-.02.045-.038.067-.058a10.323 10.323 0 0 1-1.13 13.055c-4.03 4.223-10.68 4.551-15.12.927-4.51-3.68-5.046-9.723-2.131-14.006Z" fill="#276749"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.318 5.632C19.417-.21 9.822.285 4.703 5.4c.03.033.059.067.09.098 3.383 3.283 6.766 6.564 10.145 9.848.096.093.15.082.236-.004.437-.429.878-.853 1.319-1.277 2.852-2.745 5.705-5.49 8.559-8.232.076-.073.17-.13.266-.2Zm-10.27 11.786L2.685 5.4c.03-.038.054-.075.083-.107 1.488-1.598 3.215-2.89 5.23-3.81A16.24 16.24 0 0 1 11.432.358a16.717 16.717 0 0 1 4.154-.341c2.04.088 3.992.54 5.858 1.347 2.243.97 4.137 2.386 5.745 4.176.093.103.04.15-.032.219-2 1.925-3.998 3.85-5.996 5.776l-5.982 5.767c-.036.035-.074.068-.13.117ZM9.733 14.608c-.837.742-2.699.914-3.931-.278-1.237-1.197-1.067-2.966-.255-3.886l4.186 4.164ZM20.563 14.32l4.193-4.072c.59.64.863 2.272-.158 3.476-1.136 1.338-3.01 1.33-4.035.596Z" fill="#276749"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M22.566 8.13C18.24 3.846 11.203 4.21 7.45 7.96c.022.023.043.049.066.071 2.48 2.407 4.961 4.814 7.44 7.222.07.068.11.06.173-.003.32-.314.643-.626.967-.937 2.091-2.012 4.183-4.025 6.276-6.036.056-.054.126-.095.195-.147Zm-7.53 8.643L5.968 7.961c.022-.028.04-.055.061-.078C7.12 6.71 8.387 5.763 9.865 5.089a11.91 11.91 0 0 1 2.518-.828c1.004-.209 2.02-.294 3.046-.25A12.06 12.06 0 0 1 19.725 5c1.645.711 3.034 1.75 4.212 3.063.069.076.03.11-.023.16l-4.397 4.237-4.386 4.228c-.027.026-.055.05-.095.086ZM11.137 14.712c-.614.545-1.979.67-2.883-.204-.906-.877-.782-2.174-.187-2.849l3.07 3.053ZM19.08 14.502c1.027-.999 2.05-1.993 3.074-2.986.433.469.634 1.666-.115 2.548-.833.981-2.208.976-2.96.438Z" fill="#276749"/>
</svg> </svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.467 7.495c.046.041.084.073.12.107.377.365.75.734 1.133 1.095.085.081.086.137.024.23-.8 1.21-1.09 2.537-.824 3.943.358 1.886 1.456 3.26 3.248 4.089 1.06.489 2.183.614 3.338.443a5.646 5.646 0 0 0 2.166-.788c.11-.068.17-.06.26.028.974.958 1.955 1.91 2.928 2.87.108.105.163.117.28.004 1.112-1.087 2.234-2.166 3.347-3.254.122-.12.199-.14.36-.047.973.568 2.033.795 3.167.744 2.25-.102 4.305-1.625 5.003-3.716.528-1.583.332-3.086-.529-4.515-.056-.093-.06-.15.025-.231.314-.293.619-.594.928-.891.028-.028.06-.052.092-.079 3.297 4.694 3.762 12.244-1.543 17.803-5.495 5.758-14.563 6.206-20.618 1.264-6.149-5.02-6.88-13.26-2.905-19.1Z" fill="#DD6B20"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M5.809 9.496c.034.03.062.054.088.079.276.268.55.538.83.803.064.06.064.1.019.168-.587.888-.8 1.861-.605 2.892.263 1.383 1.068 2.391 2.383 2.998.776.36 1.6.451 2.447.326a4.14 4.14 0 0 0 1.588-.578c.08-.05.125-.044.19.02.715.703 1.435 1.401 2.149 2.104.078.078.12.087.204.004.816-.797 1.639-1.589 2.455-2.386.09-.088.146-.103.264-.034.713.415 1.491.582 2.322.544 1.65-.074 3.158-1.191 3.67-2.724.387-1.161.243-2.263-.388-3.311-.041-.069-.045-.11.018-.17.23-.214.454-.435.68-.653.021-.02.045-.038.067-.058a10.323 10.323 0 0 1-1.13 13.055c-4.03 4.223-10.68 4.551-15.12.927-4.51-3.68-5.046-9.723-2.131-14.006Z" fill="#DD6B20"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.318 5.632C19.417-.21 9.822.285 4.703 5.4c.03.033.059.067.09.098 3.383 3.283 6.766 6.564 10.145 9.848.096.093.15.082.236-.004.437-.429.878-.853 1.319-1.277 2.852-2.745 5.705-5.49 8.559-8.232.076-.073.17-.13.266-.2Zm-10.27 11.786L2.685 5.4c.03-.038.054-.075.083-.107 1.488-1.598 3.215-2.89 5.23-3.81A16.24 16.24 0 0 1 11.432.358a16.717 16.717 0 0 1 4.154-.341c2.04.088 3.992.54 5.858 1.347 2.243.97 4.137 2.386 5.745 4.176.093.103.04.15-.032.219-2 1.925-3.998 3.85-5.996 5.776l-5.982 5.767c-.036.035-.074.068-.13.117ZM9.733 14.608c-.837.742-2.699.914-3.931-.278-1.237-1.197-1.067-2.966-.255-3.886l4.186 4.164ZM20.563 14.32l4.193-4.072c.59.64.863 2.272-.158 3.476-1.136 1.338-3.01 1.33-4.035.596Z" fill="#DD6B20"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M22.566 8.13C18.24 3.846 11.203 4.21 7.45 7.96c.022.023.043.049.066.071 2.48 2.407 4.961 4.814 7.44 7.222.07.068.11.06.173-.003.32-.314.643-.626.967-.937 2.091-2.012 4.183-4.025 6.276-6.036.056-.054.126-.095.195-.147Zm-7.53 8.643L5.968 7.961c.022-.028.04-.055.061-.078C7.12 6.71 8.387 5.763 9.865 5.089a11.91 11.91 0 0 1 2.518-.828c1.004-.209 2.02-.294 3.046-.25A12.06 12.06 0 0 1 19.725 5c1.645.711 3.034 1.75 4.212 3.063.069.076.03.11-.023.16l-4.397 4.237-4.386 4.228c-.027.026-.055.05-.095.086ZM11.137 14.712c-.614.545-1.979.67-2.883-.204-.906-.877-.782-2.174-.187-2.849l3.07 3.053ZM19.08 14.502c1.027-.999 2.05-1.993 3.074-2.986.433.469.634 1.666-.115 2.548-.833.981-2.208.976-2.96.438Z" fill="#DD6B20"/>
</svg> </svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.285 3.6a1.6 1.6 0 0 0-1.6-1.6H8.298a1.6 1.6 0 0 0-1.6 1.6v2.217a1.6 1.6 0 0 1-1.6 1.6H3.6a1.6 1.6 0 0 0-1.6 1.6V26.4A1.6 1.6 0 0 0 3.6 28h2.387a1.6 1.6 0 0 0 1.6-1.6V9.017a1.6 1.6 0 0 1 1.6-1.6h1.498a1.6 1.6 0 0 0 1.6-1.6V3.6Zm11.212 0a1.6 1.6 0 0 0-1.6-1.6H19.51a1.6 1.6 0 0 0-1.6 1.6v2.217a1.6 1.6 0 0 0 1.6 1.6h1.303a1.6 1.6 0 0 1 1.6 1.6V26.4a1.6 1.6 0 0 0 1.6 1.6H26.4a1.6 1.6 0 0 0 1.6-1.6V9.017a1.6 1.6 0 0 0-1.6-1.6h-1.303a1.6 1.6 0 0 1-1.6-1.6V3.6Zm-5.665 10.37a1.6 1.6 0 0 0-1.6-1.6h-2.387a1.6 1.6 0 0 0-1.6 1.6v7.323a1.6 1.6 0 0 0 1.6 1.6h2.387a1.6 1.6 0 0 0 1.6-1.6v-7.324Z" fill="currentColor"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M12.703 5.6a1.6 1.6 0 0 0-1.6-1.6H9.575a1.6 1.6 0 0 0-1.6 1.6v1.383a1.6 1.6 0 0 1-1.6 1.6H5.6a1.6 1.6 0 0 0-1.6 1.6V24.4A1.6 1.6 0 0 0 5.6 26h1.528a1.6 1.6 0 0 0 1.6-1.6V10.183a1.6 1.6 0 0 1 1.6-1.6h.775a1.6 1.6 0 0 0 1.6-1.6V5.6Zm9.487 0a1.6 1.6 0 0 0-1.6-1.6h-1.528a1.6 1.6 0 0 0-1.6 1.6v1.383a1.6 1.6 0 0 0 1.6 1.6h.61a1.6 1.6 0 0 1 1.6 1.6V24.4a1.6 1.6 0 0 0 1.6 1.6H24.4a1.6 1.6 0 0 0 1.6-1.6V10.183a1.6 1.6 0 0 0-1.6-1.6h-.61a1.6 1.6 0 0 1-1.6-1.6V5.6Zm-4.793 8.774a1.6 1.6 0 0 0-1.6-1.6h-1.528a1.6 1.6 0 0 0-1.6 1.6v5.705a1.6 1.6 0 0 0 1.6 1.6h1.528a1.6 1.6 0 0 0 1.6-1.6v-5.705Z" fill="currentColor"/>
</svg> </svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 11a2 2 0 0 1 2-2h22.753a2 2 0 0 1 1.92 1.436L30 21.75H14.25l-1.125-5.25H0V11Zm0 8.75V18h12l.75 3.75H2a2 2 0 0 1-2-2Zm6-9.25H2.25l1.5 4.5H7.5L6 10.5Zm6 0H8.25l1.5 4.5h3.75L12 10.5Zm8.25 7.5h1.821l.429 1.5h-1.821L20.25 18Zm7.071 0H25.5l.429 1.5h1.821l-.429-1.5ZM17.25 10.5h7.5L27 17.25h-7.5l-2.25-6.75Z" fill="#38B2AC"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M4 12a2 2 0 0 1 2-2h15.753a2 2 0 0 1 1.92 1.436L26 19.35H14.45l-.825-3.85H4V12Zm0 5.35v-.75h8.8l.55 2.75H6a2 2 0 0 1-2-2Zm4.4-6.25H5.65l1.1 3.3H9.5l-1.1-3.3Zm4.4 0h-2.75l1.1 3.3h2.75l-1.1-3.3Zm6.05 5.5h1.336l.314 1.1h-1.336l-.314-1.1Zm5.186 0H22.7l.314 1.1h1.336l-.314-1.1Zm-7.386-5.5h5.5l1.65 4.95h-5.5l-1.65-4.95Z" fill="#38B2AC"/>
</svg> </svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.247 3h1.616a5 5 0 0 1 0 10h-1.116v1.5a.5.5 0 0 1-.5.5h-5.116a.5.5 0 0 1-.5-.5V3.06a.06.06 0 0 1 .06-.06h5.556ZM7.678 14.678a.5.5 0 0 1 .848 0l6.601 10.557a.5.5 0 0 1-.424.765H1.501a.5.5 0 0 1-.424-.765l6.601-10.557ZM22.373 27c3.66 0 6.625-2.91 6.625-6.5S26.032 14 22.373 14c-3.66 0-6.626 2.91-6.626 6.5s2.966 6.5 6.626 6.5Z" fill="#5B2DA4"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M15.502 13.858v1.071a.5.5 0 0 1-.5.5h-3.806a.5.5 0 0 1-.5-.5V6.048c0-.027.021-.048.048-.048h5.634a3.929 3.929 0 1 1 0 7.858h-.876ZM9.07 15.32a.5.5 0 0 1 .848 0l4.994 7.986a.5.5 0 0 1-.424.765H4.501a.5.5 0 0 1-.424-.765l4.993-7.986Zm11.638 9.537c2.875 0 5.206-2.287 5.206-5.107 0-2.821-2.331-5.108-5.206-5.108-2.876 0-5.206 2.287-5.206 5.108 0 2.82 2.33 5.107 5.206 5.107Z" fill="#5B2DA4"/>
</svg> </svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.85 5.28c1.174 0 2.057-.905 2.057-1.94S16.024 1.4 14.85 1.4s-2.058.905-2.058 1.94c0 .247.05.486.143.707l.119.198-.018.01c.341.6 1.01 1.025 1.814 1.025Zm-3.058-1.92v-.02c0-1.624 1.37-2.94 3.058-2.94 1.688 0 3.057 1.316 3.057 2.94v.006l6 3.33.006-.002c1.462-.812 3.332-.33 4.177 1.076.844 1.406.343 3.204-1.12 4.016a3.129 3.129 0 0 1-.705.286v6.096c.241.065.479.16.706.286 1.462.812 1.963 2.61 1.12 4.016-.844 1.403-2.708 1.886-4.169 1.081l-6.015 3.341c-.006 1.618-1.373 2.928-3.057 2.928-1.689 0-3.058-1.316-3.058-2.94v-.005l-6-3.331-.005.002c-1.462.812-3.332.33-4.177-1.076-.844-1.406-.343-3.204 1.12-4.016.227-.126.464-.221.705-.286v-6.096a3.136 3.136 0 0 1-.705-.286C1.267 10.954.766 9.156 1.61 7.75c.845-1.406 2.715-1.888 4.177-1.076l.02.011 5.985-3.324ZM6.865 7.683l5.296-2.941a3.046 3.046 0 0 0 1.874 1.433v4.927c-.795.245-1.473.861-1.911 1.693L7.19 10.055c.25-.807.12-1.672-.326-2.373Zm4.79 6.55-5.251-2.916a3.1 3.1 0 0 1-1.542.786v5.996a3.092 3.092 0 0 1 1.615.858l5.23-2.903a4.98 4.98 0 0 1-.052-1.822Zm.602 3.213-5.038 2.797a2.85 2.85 0 0 1-.363 2.289l5.298 2.94c.39-.7 1.068-1.23 1.881-1.445v-5.123c-.718-.221-1.341-.746-1.778-1.458ZM15.564 24a3.049 3.049 0 0 1 1.989 1.484l5.298-2.943a2.85 2.85 0 0 1-.37-2.3l-5.103-2.834c-.44.736-1.078 1.277-1.814 1.5V24Zm2.351-7.992 5.308 2.947a3.092 3.092 0 0 1 1.615-.858v-5.996a3.1 3.1 0 0 1-1.541-.786l-5.332 2.96a5.037 5.037 0 0 1-.05 1.733Zm-.406-3.177 5-2.777a2.849 2.849 0 0 1 .334-2.385l-5.298-2.941a3.05 3.05 0 0 1-1.981 1.47v4.898c.813.246 1.505.879 1.945 1.735Zm-.832 13.139-.002.001.029.049c.13.257.203.543.203.839 0 1.035-.883 1.94-2.057 1.94s-2.058-.905-2.058-1.94c0-.253.053-.499.15-.725l.102-.17-.014-.007a2.064 2.064 0 0 1 1.82-1.038c.815 0 1.491.437 1.827 1.05Zm7.069-17.8-.015-.008a1.893 1.893 0 0 0-.153 1.873l.197.328c.593.795 1.745 1.064 2.68.545.997-.553 1.31-1.757.76-2.674s-1.791-1.257-2.787-.704a2.04 2.04 0 0 0-.597.498l-.085.142ZM6.12 10.038c.422-.891.088-1.987-.849-2.507-.995-.553-2.237-.212-2.787.704-.55.917-.236 2.121.76 2.674.936.52 2.09.25 2.681-.547l.195-.324ZM23.58 20.16l.194-.323c.591-.797 1.745-1.067 2.682-.547.996.553 1.31 1.757.76 2.674s-1.792 1.257-2.788.704c-.937-.52-1.27-1.616-.848-2.508Zm-20.336-.87c.937-.52 2.09-.25 2.683.547l.194.324c.422.891.088 1.987-.849 2.507-.996.553-2.237.213-2.787-.704-.55-.917-.237-2.121.76-2.674Zm10.791-4.19v2.716c-.768-.404-1.44-1.395-1.44-2.815 0-1.888 1.188-3.018 2.211-3.018s2.21 1.13 2.21 3.018c0 1.428-.678 2.422-1.452 2.822V15.1h-1.529Z" fill="#27AA8B"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M15.214 7.4c.749 0 1.288-.574 1.288-1.2S15.962 5 15.214 5s-1.288.574-1.288 1.2.54 1.2 1.288 1.2Zm.534.94a2.282 2.282 0 0 0 1.483-1.1l3.964 2.2a2.131 2.131 0 0 0-.25 1.785l-3.741 2.078c-.33-.64-.847-1.115-1.456-1.299V8.34Zm-1.144 3.667V8.321a2.28 2.28 0 0 1-1.402-1.073L9.239 9.449c.334.525.43 1.171.244 1.776l3.691 2.05c.328-.623.835-1.084 1.43-1.268Zm-1.78 2.343-3.93-2.182a2.319 2.319 0 0 1-1.154.589v4.486c.454.088.88.308 1.209.643l3.913-2.173a3.727 3.727 0 0 1-.039-1.363Zm.45 2.404-3.77 2.093a2.133 2.133 0 0 1-.271 1.714l3.964 2.2c.292-.524.799-.92 1.407-1.082v-3.833c-.537-.166-1.003-.558-1.33-1.092Zm2.475 4.906c.645.149 1.184.56 1.488 1.11L21.2 20.57a2.133 2.133 0 0 1-.276-1.721l-3.82-2.12c-.329.55-.806.954-1.356 1.121v3.811Zm1.759-5.98 3.972 2.206c.33-.335.754-.554 1.208-.643v-4.486a2.32 2.32 0 0 1-1.153-.589l-3.99 2.215a3.765 3.765 0 0 1-.037 1.297Zm-.006-9.48v.004l4.49 2.493.004-.002c1.094-.608 2.494-.247 3.125.805.632 1.052.257 2.398-.837 3.005-.17.095-.348.166-.528.214v4.562c.18.048.358.12.528.214 1.095.607 1.47 1.953.838 3.005-.63 1.05-2.026 1.411-3.119.809l-4.5 2.5C17.496 25.019 16.474 26 15.213 26c-1.263 0-2.288-.985-2.288-2.2v-.003l-4.49-2.494-.004.002c-1.094.608-2.493.247-3.125-.805-.632-1.052-.257-2.398.837-3.005.17-.095.348-.166.528-.214v-4.562a2.345 2.345 0 0 1-.527-.214c-1.095-.607-1.47-1.953-.838-3.005.632-1.052 2.031-1.413 3.125-.805l.016.008 4.478-2.488V6.2c0-1.215 1.025-2.2 2.288-2.2 1.264 0 2.288.985 2.288 2.2ZM15.214 25c.749 0 1.288-.574 1.288-1.2s-.54-1.2-1.288-1.2-1.288.574-1.288 1.2.54 1.2 1.288 1.2ZM8.396 11.215c.338-.563.15-1.314-.478-1.663-.628-.348-1.399-.13-1.737.433-.338.563-.15 1.315.478 1.663.628.348 1.399.13 1.737-.433Zm15.851 8.8c.338-.563.15-1.314-.477-1.663-.628-.348-1.399-.13-1.737.433-.338.563-.15 1.314.478 1.663.628.348 1.399.13 1.736-.433ZM6.66 18.352c.628-.348 1.398-.13 1.736.433.339.563.15 1.314-.477 1.663-.628.348-1.399.13-1.737-.433-.338-.563-.15-1.314.478-1.663Zm15.852-8.8c.628-.348 1.398-.13 1.736.433.338.563.15 1.314-.478 1.663-.627.348-1.398.13-1.736-.433-.338-.563-.15-1.315.478-1.663ZM14.605 15v1.738c-.433-.288-.826-.895-.826-1.811 0-1.33.826-2.007 1.402-2.007.577 0 1.403.677 1.403 2.007 0 .923-.399 1.532-.835 1.818V15h-1.144Z" fill="#27AA8B"/>
</svg> </svg>
\ No newline at end of file
import React from 'react';
import abiIcon from 'icons/ABI.svg';
import apiKeysIcon from 'icons/API.svg';
import appsIcon from 'icons/apps.svg';
import blocksIcon from 'icons/block.svg';
import gearIcon from 'icons/gear.svg';
import privateTagIcon from 'icons/privattags.svg';
import publicTagIcon from 'icons/publictags.svg';
import tokensIcon from 'icons/token.svg';
import transactionsIcon from 'icons/transactions.svg';
import watchlistIcon from 'icons/watchlist.svg';
import useBasePath from 'lib/hooks/useBasePath';
export default function useNavItems() {
const basePath = useBasePath();
return React.useMemo(() => {
const mainNavItems = [
{ text: 'Blocks', pathname: basePath + '/blocks', icon: blocksIcon },
{ text: 'Transactions', pathname: basePath + '/transactions', icon: transactionsIcon },
{ text: 'Tokens', pathname: basePath + '/tokens', icon: tokensIcon },
{ text: 'Apps', pathname: basePath + '/apps', icon: appsIcon },
{ text: 'Other', pathname: basePath + '/other', icon: gearIcon },
];
const accountNavItems = [
{ text: 'Watchlist', pathname: basePath + '/account/watchlist', icon: watchlistIcon },
{ text: 'Private tags', pathname: basePath + '/account/private_tags', icon: privateTagIcon },
{ text: 'Public tags', pathname: basePath + '/account/public_tags_request', icon: publicTagIcon },
{ text: 'API keys', pathname: basePath + '/account/api_key', icon: apiKeysIcon },
{ text: 'Custom ABI', pathname: basePath + '/account/custom_abi', icon: abiIcon },
];
return { mainNavItems, accountNavItems };
}, [ basePath ]);
}
import { Center, VStack, Box } from '@chakra-ui/react'; /* eslint-disable max-len */
import { Center, VStack, Box, chakra } from '@chakra-ui/react';
import type { NextPage } from 'next'; import type { NextPage } from 'next';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
...@@ -12,7 +13,16 @@ const Home: NextPage = () => { ...@@ -12,7 +13,16 @@ const Home: NextPage = () => {
<Page> <Page>
<Center h="100%" fontSize={{ base: 'sm', lg: 'xl' }}> <Center h="100%" fontSize={{ base: 'sm', lg: 'xl' }}>
<VStack gap={ 4 }> <VStack gap={ 4 }>
<Box>home page for { router.query.network_type } { router.query.network_sub_type } network</Box> <Box>
<p>home page for { router.query.network_type } { router.query.network_sub_type } network</p>
{ /* for scroll demo purpose only */ }
<chakra.p mt={ 2 }>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam at cursus nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Nam sed nisi sit amet sem iaculis tempor. Vestibulum at risus lectus. Aliquam vitae tortor bibendum, molestie erat nec, dapibus lorem. Curabitur ac tristique dolor. Maecenas condimentum ac odio vitae hendrerit. Maecenas iaculis vitae mauris id tincidunt. Fusce ac nulla mi. Aenean quis purus vehicula, ultricies quam vel, suscipit turpis. Aliquam dignissim pharetra consequat. In at urna id orci ullamcorper iaculis. Vestibulum sed dolor eu augue elementum sodales. Duis lacus arcu, vulputate id tempus et, ultricies ut augue. Nunc sit amet mi eu massa maximus viverra at in leo.</chakra.p>
<chakra.p mt={ 2 }>Aliquam hendrerit nunc non metus sollicitudin, sit amet vehicula tellus interdum. Etiam molestie, odio at dapibus bibendum, velit ante gravida dui, et viverra nibh lorem vitae tellus. Pellentesque tristique orci vitae ipsum feugiat, sed elementum odio dictum. Curabitur maximus quis enim vel bibendum. Proin elementum arcu ligula, vitae elementum diam laoreet in. Etiam mollis scelerisque risus id facilisis. Nullam dapibus dignissim consequat. Praesent faucibus tincidunt metus, quis posuere tortor ullamcorper a. Fusce porttitor mollis dui a aliquam. Nunc congue tellus euismod elit aliquet, eget posuere purus gravida. Morbi ultrices pretium interdum. Phasellus ultricies felis euismod malesuada luctus.</chakra.p>
<chakra.p mt={ 2 }>Nulla eget accumsan mauris. Aliquam ultrices porta diam, a viverra dui aliquam quis. Praesent porttitor ultricies volutpat. Ut sem metus, venenatis in lacus placerat, rhoncus ornare dolor. In hac habitasse platea dictumst. Nullam ac ornare quam. Aenean sed congue nisl. Mauris malesuada egestas erat, a finibus purus consequat nec. Mauris congue scelerisque urna non faucibus. Sed vehicula vitae sem eu varius. In sit amet nunc non metus fermentum finibus.</chakra.p>
<chakra.p mt={ 2 }>Nulla sollicitudin fringilla mauris in ornare. Donec consectetur ultricies lorem ac rhoncus. Mauris dictum vestibulum sollicitudin. Cras in orci eget urna sollicitudin auctor. Suspendisse pellentesque eget purus nec facilisis. Nunc in vulputate odio. Aenean viverra malesuada consequat. Quisque eleifend faucibus aliquam. Aenean dui erat, ultricies quis iaculis sed, malesuada eleifend justo. Proin sollicitudin venenatis cursus. Mauris quis enim mollis, lacinia metus in, luctus ligula.</chakra.p>
<chakra.p mt={ 2 }>Vestibulum eget mollis arcu, sed malesuada massa. Nunc at est vel felis scelerisque sollicitudin. Vestibulum vulputate ipsum sapien, eu vestibulum nibh maximus tincidunt. Sed posuere fermentum leo nec bibendum. Cras tincidunt dui ullamcorper lectus luctus, vitae consequat velit scelerisque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec eleifend imperdiet ultrices. Etiam ullamcorper mi semper interdum iaculis. Suspendisse urna lacus, egestas ut vehicula non, varius non diam. Nunc consequat eros in accumsan interdum. Morbi blandit risus sollicitudin, suscipit nisl at, malesuada est. Vestibulum eget molestie diam. Suspendisse potenti.</chakra.p>
<chakra.p mt={ 2 }>Pellentesque enim risus, elementum ut ornare id, faucibus in urna. Sed laoreet iaculis augue in fermentum. Morbi nec lacus pharetra, condimentum justo eget, commodo est. Donec nec auctor sapien, eget fringilla nisl. Aliquam ac ex rhoncus, tempor augue quis, aliquet sapien. Curabitur ullamcorper lacus orci, eget placerat velit sollicitudin non. Praesent imperdiet convallis tincidunt. Aliquam venenatis ultricies orci. Mauris accumsan volutpat magna vel condimentum. Donec et volutpat enim. Cras ac purus eget ex bibendum sollicitudin sed eget ligula. Nunc magna velit, feugiat in accumsan quis, aliquet posuere lorem. Proin dapibus leo sem, vitae dignissim odio malesuada eget. Donec venenatis pretium porta. In tempus eros at magna consectetur, id pellentesque magna iaculis.</chakra.p>
</Box>
</VStack> </VStack>
</Center> </Center>
</Page> </Page>
......
import type { drawerAnatomy as parts } from '@chakra-ui/anatomy';
import type { SystemStyleFunction, PartsStyleFunction, SystemStyleObject } from '@chakra-ui/theme-tools';
import { mode } from '@chakra-ui/theme-tools';
const baseStyleOverlay: SystemStyleObject = {
bg: 'blackAlpha.800',
zIndex: 'overlay',
};
const baseStyleDialog: SystemStyleFunction = (props) => {
const { isFullHeight } = props;
return {
...(isFullHeight && { height: '100vh' }),
zIndex: 'modal',
maxH: '100vh',
bg: mode('white', 'gray.900')(props),
color: 'inherit',
boxShadow: mode('lg', 'dark-lg')(props),
};
};
const baseStyle: PartsStyleFunction<typeof parts> = (props) => ({
overlay: baseStyleOverlay,
dialog: baseStyleDialog(props),
});
const Drawer = {
baseStyle,
};
export default Drawer;
...@@ -8,6 +8,14 @@ import getDefaultTransitionProps from '../utils/getDefaultTransitionProps'; ...@@ -8,6 +8,14 @@ import getDefaultTransitionProps from '../utils/getDefaultTransitionProps';
import getOutlinedFieldStyles from '../utils/getOutlinedFieldStyles'; import getOutlinedFieldStyles from '../utils/getOutlinedFieldStyles';
const sizes: Record<string, SystemStyleObject> = { const sizes: Record<string, SystemStyleObject> = {
sm: {
fontSize: 'md',
lineHeight: '24px',
px: '8px',
py: '12px',
h: '40px',
borderRadius: 'base',
},
md: { md: {
fontSize: 'md', fontSize: 'md',
lineHeight: '20px', lineHeight: '20px',
...@@ -43,6 +51,10 @@ const variantOutline: PartsStyleFunction<typeof parts> = (props) => { ...@@ -43,6 +51,10 @@ const variantOutline: PartsStyleFunction<typeof parts> = (props) => {
const Input: ComponentStyleConfig = { const Input: ComponentStyleConfig = {
sizes: { sizes: {
sm: {
field: sizes.sm,
addon: sizes.sm,
},
md: { md: {
field: sizes.md, field: sizes.md,
addon: sizes.md, addon: sizes.md,
......
import Button from './Button'; import Button from './Button';
import Checkbox from './Checkbox'; import Checkbox from './Checkbox';
import Drawer from './Drawer';
import Form from './Form'; import Form from './Form';
import Heading from './Heading'; import Heading from './Heading';
import Input from './Input'; import Input from './Input';
...@@ -18,6 +19,7 @@ import Tooltip from './Tooltip'; ...@@ -18,6 +19,7 @@ import Tooltip from './Tooltip';
const components = { const components = {
Button, Button,
Checkbox, Checkbox,
Drawer,
Heading, Heading,
Input, Input,
Form, Form,
......
...@@ -3,8 +3,8 @@ const breakpoints = { ...@@ -3,8 +3,8 @@ const breakpoints = {
// sm: '320px', // sm: '320px',
// md: '768px', // md: '768px',
lg: '1000px', lg: '1000px',
// these breakpoints are needed just to make "lg" work xl: '1440px',
xl: '2000px', // these breakpoint are needed just to make others work
'2xl': '3000px', '2xl': '3000px',
}; };
......
import { Icon, Box, Flex, Drawer, DrawerOverlay, DrawerContent, DrawerBody, useColorModeValue, useDisclosure } from '@chakra-ui/react';
import React from 'react';
import burgerIcon from 'icons/burger.svg';
import NavigationMobile from 'ui/blocks/navigation/NavigationMobile';
import NetworkLogo from 'ui/blocks/networkMenu/NetworkLogo';
import NetworkMenuButton from 'ui/blocks/networkMenu/NetworkMenuButton';
import NetworkMenuContentMobile from 'ui/blocks/networkMenu/NetworkMenuContentMobile';
const Burger = () => {
const iconColor = useColorModeValue('gray.600', 'white');
const { isOpen, onOpen, onClose } = useDisclosure();
const [ isNetworkMenuOpened, setNetworkMenuVisibility ] = React.useState(false);
const handleNetworkMenuButtonClick = React.useCallback(() => {
setNetworkMenuVisibility((flag) => !flag);
}, []);
const handleNetworkLogoClick = React.useCallback((event: React.SyntheticEvent) => {
isNetworkMenuOpened && event.preventDefault();
setNetworkMenuVisibility(false);
}, [ isNetworkMenuOpened ]);
return (
<>
<Box padding={ 2 } onClick={ onOpen }>
<Icon
as={ burgerIcon }
boxSize={ 6 }
display="block"
color={ iconColor }
/>
</Box>
<Drawer
isOpen={ isOpen }
placement="left"
onClose={ onClose }
autoFocus={ false }
>
<DrawerOverlay/>
<DrawerContent maxWidth="260px">
<DrawerBody p={ 6 }>
<Flex alignItems="center" justifyContent="space-between">
<NetworkLogo onClick={ handleNetworkLogoClick }/>
<NetworkMenuButton
isMobile
isActive={ isNetworkMenuOpened }
onClick={ handleNetworkMenuButtonClick }
/>
</Flex>
{ isNetworkMenuOpened ? <NetworkMenuContentMobile/> : <NavigationMobile/> }
</DrawerBody>
</DrawerContent>
</Drawer>
</>
);
};
export default Burger;
...@@ -15,8 +15,9 @@ import { ...@@ -15,8 +15,9 @@ import {
import { dataAttr, __DEV__ } from '@chakra-ui/utils'; import { dataAttr, __DEV__ } from '@chakra-ui/utils';
import * as React from 'react'; import * as React from 'react';
import moonIcon from '../../icons/moon.svg'; import moonIcon from 'icons/moon.svg';
import getDefaultTransitionProps from '../../theme/utils/getDefaultTransitionProps'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import styles from './ColorModeToggler.module.css'; import styles from './ColorModeToggler.module.css';
export interface ColorModeTogglerProps export interface ColorModeTogglerProps
......
import { HStack, Box, Flex, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
import useIsMobile from 'lib/hooks/useIsMobile';
import NetworkLogo from 'ui/blocks/networkMenu/NetworkLogo';
import SearchBar from 'ui/blocks/searchBar/SearchBar';
import Burger from './Burger';
import ColorModeToggler from './ColorModeToggler';
import ProfileMenu from './ProfileMenu';
const Header = () => {
const isMobile = useIsMobile();
const bgColor = useColorModeValue('white', 'black');
if (isMobile) {
return (
<Box bgColor={ bgColor }>
<Flex
as="header"
position="fixed"
top={ 0 }
left={ 0 }
paddingX={ 4 }
paddingY={ 2 }
bgColor={ bgColor }
width="100%"
alignItems="center"
justifyContent="space-between"
zIndex={ 10 }
>
<Burger/>
<NetworkLogo/>
<ProfileMenu/>
</Flex>
<SearchBar/>
</Box>
);
}
return (
<HStack
as="header"
width="100%"
alignItems="center"
justifyContent="center"
gap={ 12 }
>
<SearchBar/>
<ColorModeToggler/>
<ProfileMenu/>
</HStack>
);
};
export default Header;
import { Center, useColorModeValue, chakra } from '@chakra-ui/react';
import React from 'react';
import Identicon from 'react-identicons';
import useIsMobile from 'lib/hooks/useIsMobile';
const ProfileIcon = chakra(Identicon);
const ProfileMenu = () => {
const isMobile = useIsMobile();
const size = isMobile ? '24px' : '50px';
return (
<Center
flexShrink={ 0 }
padding={ isMobile ? 2 : 0 }
>
{ /* the displayed size is 48px, but we need to generate x2 for retina displays */ }
<ProfileIcon
maxWidth={ size }
maxHeight={ size }
string="randomness"
size={ 100 }
bg={ useColorModeValue('blackAlpha.100', 'white') }
borderRadius="50%"
overflow="hidden"
/>
</Center>
);
};
export default ProfileMenu;
...@@ -5,6 +5,7 @@ import ghIcon from 'icons/social/git.svg'; ...@@ -5,6 +5,7 @@ import ghIcon from 'icons/social/git.svg';
import statsIcon from 'icons/social/stats.svg'; import statsIcon from 'icons/social/stats.svg';
import tgIcon from 'icons/social/telega.svg'; import tgIcon from 'icons/social/telega.svg';
import twIcon from 'icons/social/tweet.svg'; import twIcon from 'icons/social/tweet.svg';
import useIsMobile from 'lib/hooks/useIsMobile';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
const SOCIAL_LINKS = [ const SOCIAL_LINKS = [
...@@ -18,19 +19,29 @@ const BLOCKSCOUT_VERSION = process.env.NEXT_PUBLIC_BLOCKSCOUT_VERSION; ...@@ -18,19 +19,29 @@ const BLOCKSCOUT_VERSION = process.env.NEXT_PUBLIC_BLOCKSCOUT_VERSION;
const VERSION_URL = `https://github.com/blockscout/blockscout/tree/${ BLOCKSCOUT_VERSION }`; const VERSION_URL = `https://github.com/blockscout/blockscout/tree/${ BLOCKSCOUT_VERSION }`;
interface Props { interface Props {
isCollapsed: boolean; isCollapsed?: boolean;
} }
const NavFooter = ({ isCollapsed }: Props) => { const NavFooter = ({ isCollapsed }: Props) => {
const isMobile = useIsMobile();
const width = (() => {
if (isMobile) {
return '100%';
}
return isCollapsed ? '20px' : '180px';
})();
return ( return (
<VStack <VStack
as="footer" as="footer"
spacing={ 8 } spacing={ 8 }
borderTop="1px solid" borderTop="1px solid"
borderColor={ useColorModeValue('blackAlpha.200', 'whiteAlpha.200') } borderColor={ useColorModeValue('blackAlpha.200', 'whiteAlpha.200') }
width={ isCollapsed ? '20px' : '180px' } width={ width }
paddingTop={ 8 } paddingTop={ isMobile ? 6 : 8 }
marginTop={ 20 } marginTop={ isMobile ? 6 : 20 }
alignItems="flex-start" alignItems="flex-start"
color="gray.500" color="gray.500"
fontSize="xs" fontSize="xs"
......
...@@ -2,12 +2,13 @@ import { Link, Icon, Text, HStack, Tooltip } from '@chakra-ui/react'; ...@@ -2,12 +2,13 @@ import { Link, Icon, Text, HStack, Tooltip } from '@chakra-ui/react';
import NextLink from 'next/link'; import NextLink from 'next/link';
import React from 'react'; import React from 'react';
import useIsMobile from 'lib/hooks/useIsMobile';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import useColors from './useColors'; import useColors from './useColors';
interface Props { interface Props {
isCollapsed: boolean; isCollapsed?: boolean;
isActive: boolean; isActive: boolean;
pathname: string; pathname: string;
text: string; text: string;
...@@ -16,13 +17,21 @@ interface Props { ...@@ -16,13 +17,21 @@ interface Props {
const NavLink = ({ text, pathname, icon, isCollapsed, isActive }: Props) => { const NavLink = ({ text, pathname, icon, isCollapsed, isActive }: Props) => {
const colors = useColors(); const colors = useColors();
const isMobile = useIsMobile();
const width = (() => {
if (isMobile) {
return '100%';
}
return isCollapsed ? '60px' : '180px';
})();
return ( return (
<NextLink href={ pathname } passHref> <NextLink href={ pathname } passHref>
<Link <Link
as="li" as="li"
listStyleType="none" listStyleType="none"
w={ isCollapsed ? '60px' : '180px' } w={ width }
px={ isCollapsed ? '15px' : 3 } px={ isCollapsed ? '15px' : 3 }
py={ 2.5 } py={ 2.5 }
color={ isActive ? colors.text.active : colors.text.default } color={ isActive ? colors.text.active : colors.text.default }
...@@ -43,7 +52,7 @@ const NavLink = ({ text, pathname, icon, isCollapsed, isActive }: Props) => { ...@@ -43,7 +52,7 @@ const NavLink = ({ text, pathname, icon, isCollapsed, isActive }: Props) => {
> >
<HStack spacing={ 3 }> <HStack spacing={ 3 }>
<Icon as={ icon } boxSize="30px"/> <Icon as={ icon } boxSize="30px"/>
{ !isCollapsed && <Text variant="inherit">{ text }</Text> } { !isCollapsed && <Text variant="inherit" fontSize="sm" lineHeight="20px">{ text }</Text> }
</HStack> </HStack>
</Tooltip> </Tooltip>
</Link> </Link>
......
import { ChevronLeftIcon } from '@chakra-ui/icons'; import { ChevronLeftIcon } from '@chakra-ui/icons';
import { Flex, Icon, Box, VStack, useColorModeValue } from '@chakra-ui/react'; import { Flex, Box, VStack, useColorModeValue, useBreakpointValue } from '@chakra-ui/react';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import abiIcon from 'icons/ABI.svg';
import apiKeysIcon from 'icons/API.svg';
import appsIcon from 'icons/apps.svg';
import blocksIcon from 'icons/block.svg';
import gearIcon from 'icons/gear.svg';
import logoIcon from 'icons/logo.svg';
import privateTagIcon from 'icons/privattags.svg';
import publicTagIcon from 'icons/publictags.svg';
import tokensIcon from 'icons/token.svg';
import transactionsIcon from 'icons/transactions.svg';
import watchlistIcon from 'icons/watchlist.svg';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
import useBasePath from 'lib/hooks/useBasePath'; import useNavItems from 'lib/hooks/useNavItems';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import NetworkLogo from 'ui/blocks/networkMenu/NetworkLogo';
import NetworkMenu from 'ui/blocks/networkMenu/NetworkMenu';
import NavFooter from './NavFooter'; import NavFooter from './NavFooter';
import NavLink from './NavLink'; import NavLink from './NavLink';
import NetworkMenu from './networkMenu/NetworkMenu';
const Navigation = () => { const NavigationDesktop = () => {
const router = useRouter(); const router = useRouter();
const basePath = useBasePath();
const mainNavItems = [ const { mainNavItems, accountNavItems } = useNavItems();
{ text: 'Blocks', pathname: basePath + '/blocks', icon: blocksIcon }, const isLargeScreen = useBreakpointValue({ base: false, xl: true });
{ text: 'Transactions', pathname: basePath + '/transactions', icon: transactionsIcon }, const cookieValue = cookies.get(cookies.NAMES.NAV_BAR_COLLAPSED);
{ text: 'Tokens', pathname: basePath + '/tokens', icon: tokensIcon },
{ text: 'Apps', pathname: basePath + '/apps', icon: appsIcon },
{ text: 'Other', pathname: basePath + '/other', icon: gearIcon },
];
const accountNavItems = [ const [ isCollapsed, setCollapsedState ] = React.useState(cookieValue === 'true');
{ text: 'Watchlist', pathname: basePath + '/account/watchlist', icon: watchlistIcon },
{ text: 'Private tags', pathname: basePath + '/account/private_tags', icon: privateTagIcon },
{ text: 'Public tags', pathname: basePath + '/account/public_tags_request', icon: publicTagIcon },
{ text: 'API keys', pathname: basePath + '/account/api_key', icon: apiKeysIcon },
{ text: 'Custom ABI', pathname: basePath + '/account/custom_abi', icon: abiIcon },
];
const [ isCollapsed, setCollapsedState ] = React.useState(cookies.get(cookies.NAMES.NAV_BAR_COLLAPSED) === 'true'); React.useEffect(() => {
if (!cookieValue) {
setCollapsedState(!isLargeScreen);
}
}, [ isLargeScreen, cookieValue ]);
const handleTogglerClick = React.useCallback(() => { const handleTogglerClick = React.useCallback(() => {
setCollapsedState((flag) => !flag); setCollapsedState((flag) => !flag);
cookies.set(cookies.NAMES.NAV_BAR_COLLAPSED, isCollapsed ? 'false' : 'true'); cookies.set(cookies.NAMES.NAV_BAR_COLLAPSED, isCollapsed ? 'false' : 'true');
}, [ isCollapsed ]); }, [ isCollapsed ]);
const logoColor = useColorModeValue('blue.600', 'white'); const containerBorderColor = useColorModeValue('blackAlpha.200', 'whiteAlpha.200');
const chevronIconStyles = {
bgColor: useColorModeValue('white', 'black'),
color: useColorModeValue('blackAlpha.400', 'whiteAlpha.400'),
borderColor: useColorModeValue('blackAlpha.200', 'whiteAlpha.200'),
};
return ( return (
<Flex <Flex
...@@ -57,7 +45,7 @@ const Navigation = () => { ...@@ -57,7 +45,7 @@ const Navigation = () => {
flexDirection="column" flexDirection="column"
alignItems="center" alignItems="center"
borderRight="1px solid" borderRight="1px solid"
borderColor={ useColorModeValue('blackAlpha.200', 'whiteAlpha.200') } borderColor={ containerBorderColor }
px={ isCollapsed ? 4 : 6 } px={ isCollapsed ? 4 : 6 }
py={ 12 } py={ 12 }
width={ isCollapsed ? '92px' : '229px' } width={ isCollapsed ? '92px' : '229px' }
...@@ -73,20 +61,7 @@ const Navigation = () => { ...@@ -73,20 +61,7 @@ const Navigation = () => {
px={ 3 } px={ 3 }
h={ 10 } h={ 10 }
> >
<Box <NetworkLogo isCollapsed={ isCollapsed }/>
width={ isCollapsed ? '0' : '113px' }
display="inline-flex"
overflow="hidden"
{ ...getDefaultTransitionProps({ transitionProperty: 'width' }) }
>
<Icon
as={ logoIcon }
width="113px"
height="20px"
color={ logoColor }
{ ...getDefaultTransitionProps() }
/>
</Box>
<NetworkMenu isCollapsed={ isCollapsed }/> <NetworkMenu isCollapsed={ isCollapsed }/>
</Box> </Box>
<Box as="nav" mt={ 14 }> <Box as="nav" mt={ 14 }>
...@@ -103,12 +78,10 @@ const Navigation = () => { ...@@ -103,12 +78,10 @@ const Navigation = () => {
<ChevronLeftIcon <ChevronLeftIcon
width={ 6 } width={ 6 }
height={ 6 } height={ 6 }
bgColor={ useColorModeValue('white', 'black') }
border="1px" border="1px"
color={ useColorModeValue('blackAlpha.400', 'whiteAlpha.400') }
_hover={{ color: 'blue.400' }} _hover={{ color: 'blue.400' }}
borderColor={ useColorModeValue('blackAlpha.200', 'whiteAlpha.200') }
borderRadius="base" borderRadius="base"
{ ...chevronIconStyles }
transform={ isCollapsed ? 'rotate(180deg)' : 'rotate(0)' } transform={ isCollapsed ? 'rotate(180deg)' : 'rotate(0)' }
{ ...getDefaultTransitionProps({ transitionProperty: 'transform, left' }) } { ...getDefaultTransitionProps({ transitionProperty: 'transform, left' }) }
transformOrigin="center" transformOrigin="center"
...@@ -122,4 +95,4 @@ const Navigation = () => { ...@@ -122,4 +95,4 @@ const Navigation = () => {
); );
}; };
export default Navigation; export default NavigationDesktop;
import { Box, VStack } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
import useNavItems from 'lib/hooks/useNavItems';
import NavFooter from 'ui/blocks/navigation/NavFooter';
import NavLink from 'ui/blocks/navigation/NavLink';
const NavigationMobile = () => {
const { mainNavItems, accountNavItems } = useNavItems();
const router = useRouter();
return (
<>
<Box as="nav" mt={ 6 }>
<VStack as="ul" spacing="2" alignItems="flex-start" overflow="hidden">
{ mainNavItems.map((item) => <NavLink key={ item.text } { ...item } isActive={ router.asPath === item.pathname }/>) }
</VStack>
</Box>
<Box as="nav" mt={ 6 }>
<VStack as="ul" spacing="2" alignItems="flex-start" overflow="hidden">
{ accountNavItems.map((item) => <NavLink key={ item.text } { ...item } isActive={ router.asPath === item.pathname }/>) }
</VStack>
</Box>
<NavFooter/>
</>
);
};
export default NavigationMobile;
import { Icon, Box, useColorModeValue } from '@chakra-ui/react';
import NextLink from 'next/link';
import React from 'react';
import logoIcon from 'icons/logo.svg';
import useBasePath from 'lib/hooks/useBasePath';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
interface Props {
isCollapsed?: boolean;
onClick?: (event: React.SyntheticEvent) => void;
}
const NetworkLogo = ({ isCollapsed, onClick }: Props) => {
const logoColor = useColorModeValue('blue.600', 'white');
const href = useBasePath();
return (
<NextLink href={ href } passHref>
<Box
as="a"
width={ isCollapsed ? '0' : '113px' }
display="inline-flex"
overflow="hidden"
onClick={ onClick }
{ ...getDefaultTransitionProps({ transitionProperty: 'width' }) }
>
<Icon
as={ logoIcon }
width="113px"
height="20px"
color={ logoColor }
{ ...getDefaultTransitionProps() }
/>
</Box>
</NextLink>
);
};
export default React.memo(NetworkLogo);
import { Popover, PopoverTrigger, Box } from '@chakra-ui/react';
import React from 'react';
import NetworkMenuButton from './NetworkMenuButton';
import NetworkMenuContentDesktop from './NetworkMenuContentDesktop';
interface Props {
isCollapsed: boolean;
}
const NetworkMenu = ({ isCollapsed }: Props) => {
return (
<Popover openDelay={ 300 } placement="right-start" gutter={ 22 } isLazy>
{ ({ isOpen }) => (
<>
<PopoverTrigger>
<Box marginLeft={ isCollapsed ? '0px' : '7px' }>
<NetworkMenuButton isActive={ isOpen }/>
</Box>
</PopoverTrigger>
<NetworkMenuContentDesktop/>
</>
) }
</Popover>
);
};
export default React.memo(NetworkMenu);
import { Icon, useColorModeValue, Button } from '@chakra-ui/react';
import React from 'react';
import networksIcon from 'icons/networks.svg';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
interface Props {
isMobile?: boolean;
isActive?: boolean;
onClick?: () => void;
}
const NetworkMenuButton = ({ isMobile, isActive, onClick }: Props, ref: React.ForwardedRef<HTMLButtonElement>) => {
const defaultIconColor = useColorModeValue('gray.600', 'gray.400');
const bgColorMobile = useColorModeValue('blue.50', 'gray.800');
const iconColorMobile = useColorModeValue('blue.700', 'blue.50');
return (
<Button
variant="unstyled"
display="inline-flex"
alignSelf="stretch"
alignItems="center"
ref={ ref }
h="36px"
borderRadius="base"
backgroundColor={ isActive ? bgColorMobile : 'none' }
onClick={ onClick }
>
<Icon
as={ networksIcon }
width="36px"
height="36px"
padding="10px"
color={ isActive ? iconColorMobile : defaultIconColor }
_hover={{ color: isMobile ? undefined : 'blue.400' }}
cursor="pointer"
{ ...getDefaultTransitionProps({ transitionProperty: 'margin' }) }
/>
</Button>
);
};
export default React.forwardRef(NetworkMenuButton);
import { Box, Select, VStack } from '@chakra-ui/react';
import capitalize from 'lodash/capitalize';
import { useRouter } from 'next/router';
import React from 'react';
import type { NetworkGroup } from 'types/networks';
import { NETWORKS } from 'lib/networks';
import NetworkMenuLink from './NetworkMenuLink';
const TABS: Array<NetworkGroup> = [ 'mainnets', 'testnets', 'other' ];
const NetworkMenuContentMobile = () => {
const router = useRouter();
const routeName = router.pathname.replace('/[network_type]/[network_sub_type]', '');
const selectedNetwork = NETWORKS.find((network) => router.query.network_type === network.type && router.query.network_sub_type === network.subType);
const [ selectedTab, setSelectedTab ] = React.useState<NetworkGroup>(TABS.find((tab) => selectedNetwork?.group === tab) || 'mainnets');
const handleSelectChange = React.useCallback((event: React.ChangeEvent<HTMLSelectElement>) => {
setSelectedTab(event.target.value as NetworkGroup);
}, []);
return (
<Box mt={ 6 }>
<Select size="sm" borderRadius="base" value={ selectedTab } onChange={ handleSelectChange } focusBorderColor="none">
{ TABS.map((tab) => <option key={ tab } value={ tab }>{ capitalize(tab) }</option>) }
</Select>
<VStack as="ul" spacing={ 2 } alignItems="stretch" mt={ 6 }>
{ NETWORKS
.filter(({ group }) => group === selectedTab)
.map((network) => (
<NetworkMenuLink
key={ network.name }
{ ...network }
isActive={ network.name === selectedNetwork?.name }
routeName={ routeName }
isMobile
/>
))
}
</VStack>
</Box>
);
};
export default NetworkMenuContentMobile;
...@@ -12,10 +12,11 @@ import useColors from './useColors'; ...@@ -12,10 +12,11 @@ import useColors from './useColors';
interface Props extends Network { interface Props extends Network {
isActive: boolean; isActive: boolean;
isMobile?: boolean;
routeName: string; routeName: string;
} }
const NetworkMenuLink = ({ name, type, subType, icon, isActive, routeName, isAccountSupported }: Props) => { const NetworkMenuLink = ({ name, type, subType, icon, isActive, isMobile, routeName, isAccountSupported }: Props) => {
const isAccount = isAccountRoute(routeName); const isAccount = isAccountRoute(routeName);
const localPath = (() => { const localPath = (() => {
if (isAccount && isAccountSupported) { if (isAccount && isAccountSupported) {
...@@ -51,8 +52,8 @@ const NetworkMenuLink = ({ name, type, subType, icon, isActive, routeName, isAcc ...@@ -51,8 +52,8 @@ const NetworkMenuLink = ({ name, type, subType, icon, isActive, routeName, isAcc
<NextLink href={ href } passHref> <NextLink href={ href } passHref>
<Flex <Flex
as="a" as="a"
px={ 4 } px={ isMobile ? 3 : 4 }
py={ 3 } py={ 2 }
alignItems="center" alignItems="center"
cursor="pointer" cursor="pointer"
pointerEvents={ isActive ? 'none' : 'initial' } pointerEvents={ isActive ? 'none' : 'initial' }
...@@ -66,6 +67,8 @@ const NetworkMenuLink = ({ name, type, subType, icon, isActive, routeName, isAcc ...@@ -66,6 +67,8 @@ const NetworkMenuLink = ({ name, type, subType, icon, isActive, routeName, isAcc
marginLeft={ 3 } marginLeft={ 3 }
fontWeight="500" fontWeight="500"
color="inherit" color="inherit"
fontSize={ isMobile ? 'sm' : 'md' }
lineHeight={ isMobile ? '20px' : '24px' }
> >
{ name } { name }
</Text> </Text>
......
import type { ChangeEvent, FormEvent } from 'react';
import React from 'react';
import useBasePath from 'lib/hooks/useBasePath';
import useIsMobile from 'lib/hooks/useIsMobile';
import SearchBarDesktop from './SearchBarDesktop';
import SearchBarMobile from './SearchBarMobile';
const SearchBar = () => {
const [ value, setValue ] = React.useState('');
const basePath = useBasePath();
const isMobile = useIsMobile();
const handleChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
}, []);
const handleSubmit = React.useCallback((event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
window.location.assign(`https://blockscout.com${ basePath }/search-results?q=${ value }`);
}, [ value, basePath ]);
if (isMobile) {
return (
<SearchBarMobile onChange={ handleChange } onSubmit={ handleSubmit }/>
);
}
return (
<SearchBarDesktop onChange={ handleChange } onSubmit={ handleSubmit }/>
);
};
export default SearchBar;
import { SearchIcon } from '@chakra-ui/icons'; import { SearchIcon } from '@chakra-ui/icons';
import { InputGroup, Input, InputLeftAddon, InputLeftElement, useColorModeValue } from '@chakra-ui/react'; import { InputGroup, Input, InputLeftAddon, InputLeftElement, useColorModeValue } from '@chakra-ui/react';
import type { ChangeEvent, FormEvent } from 'react';
import React from 'react'; import React from 'react';
import type { ChangeEvent, FormEvent } from 'react';
import useBasePath from 'lib/hooks/useBasePath'; interface Props {
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
const SearchBar = () => { onSubmit: (event: FormEvent<HTMLFormElement>) => void;
const [ value, setValue ] = React.useState(''); }
const basePath = useBasePath();
const handleChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
}, []);
const handleSubmit = React.useCallback((event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
window.location.assign(`https://blockscout.com${ basePath }/search-results?q=${ value }`);
}, [ value, basePath ]);
const SearchBarDesktop = ({ onChange, onSubmit }: Props) => {
return ( return (
<form noValidate onSubmit={ handleSubmit }> <form noValidate onSubmit={ onSubmit }>
<InputGroup> <InputGroup>
<InputLeftAddon w="111px">All filters</InputLeftAddon> <InputLeftAddon w="111px">All filters</InputLeftAddon>
<InputLeftElement w={ 6 } ml="132px" mr={ 2.5 }> <InputLeftElement w={ 6 } ml="132px" mr={ 2.5 }>
...@@ -29,7 +20,7 @@ const SearchBar = () => { ...@@ -29,7 +20,7 @@ const SearchBar = () => {
paddingInlineStart="50px" paddingInlineStart="50px"
placeholder="Search by addresses / transactions / block / token... " placeholder="Search by addresses / transactions / block / token... "
ml="1px" ml="1px"
onChange={ handleChange } onChange={ onChange }
borderColor={ useColorModeValue('blackAlpha.100', 'whiteAlpha.200') } borderColor={ useColorModeValue('blackAlpha.100', 'whiteAlpha.200') }
/> />
</InputGroup> </InputGroup>
...@@ -37,4 +28,4 @@ const SearchBar = () => { ...@@ -37,4 +28,4 @@ const SearchBar = () => {
); );
}; };
export default SearchBar; export default React.memo(SearchBarDesktop);
import { SearchIcon } from '@chakra-ui/icons';
import { InputGroup, Input, InputLeftElement, useColorModeValue, chakra } from '@chakra-ui/react';
import clamp from 'lodash/clamp';
import throttle from 'lodash/throttle';
import React from 'react';
import type { ChangeEvent, FormEvent } from 'react';
import isBrowser from 'lib/isBrowser';
const SCROLL_DIFF_THRESHOLD = 20;
interface Props {
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
onSubmit: (event: FormEvent<HTMLFormElement>) => void;
}
const SearchBarMobile = ({ onChange, onSubmit }: Props) => {
const prevScrollPosition = React.useRef(isBrowser() ? window.pageYOffset : 0);
const [ isVisible, setVisibility ] = React.useState(true);
const searchIconColor = useColorModeValue('blackAlpha.600', 'whiteAlpha.600');
const inputBorderColor = useColorModeValue('blackAlpha.100', 'whiteAlpha.200');
const bgColor = useColorModeValue('white', 'black');
const handleScroll = React.useCallback(() => {
const currentScrollPosition = clamp(window.pageYOffset, 0, window.document.body.scrollHeight - window.innerHeight);
const scrollDiff = currentScrollPosition - prevScrollPosition.current;
if (Math.abs(scrollDiff) > SCROLL_DIFF_THRESHOLD) {
setVisibility(scrollDiff > 0 ? false : true);
}
prevScrollPosition.current = currentScrollPosition;
}, []);
React.useEffect(() => {
const throttledHandleScroll = throttle(handleScroll, 300);
window.addEventListener('scroll', throttledHandleScroll);
return () => {
window.removeEventListener('scroll', throttledHandleScroll);
};
// replicate componentDidMount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<chakra.form
noValidate
onSubmit={ onSubmit }
paddingX={ 4 }
paddingTop={ 1 }
paddingBottom={ 2 }
position="fixed"
top="56px"
left="0"
bgColor={ bgColor }
transform={ isVisible ? 'translateY(0)' : 'translateY(-100%)' }
transitionProperty="transform"
transitionDuration="slow"
>
<InputGroup size="sm">
<InputLeftElement >
<SearchIcon w={ 4 } h={ 4 } color={ searchIconColor }/>
</InputLeftElement>
<Input
paddingInlineStart="38px"
placeholder="Search by addresses / ... "
ml="1px"
onChange={ onChange }
borderColor={ inputBorderColor }
/>
</InputGroup>
</chakra.form>
);
};
export default React.memo(SearchBarMobile);
.identicon {
max-width: 48px;
max-height: 48px;
}
\ No newline at end of file
import { HStack, Center, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
import Identicon from 'react-identicons';
import ColorModeToggler from './ColorModeToggler';
import styles from './Header.module.css';
import SearchBar from './SearchBar';
const Header = () => {
return (
<HStack
as="header"
height="60px"
width="100%"
alignItems="center"
justifyContent="center"
marginTop={ 9 }
gap={ 12 }
>
<SearchBar/>
<ColorModeToggler/>
<Center minWidth="50px" width="50px" height="50px" bg={ useColorModeValue('blackAlpha.100', 'white') } borderRadius="50%" overflow="hidden">
{ /* the displayed size is 48px, but we need to generate x2 for retina displays */ }
<Identicon className={ styles.identicon } string="randomness" size={ 96 }/>
</Center>
</HStack>
);
};
export default Header;
import { Popover, PopoverTrigger, Icon, useColorModeValue, Button } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
import networksIcon from 'icons/networks.svg';
import * as cookies from 'lib/cookies';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import NetworkMenuPopup from './NetworkMenuPopup';
interface Props {
isCollapsed: boolean;
}
const NetworkMenu = ({ isCollapsed }: Props) => {
const router = useRouter();
const networkType = router.query.network_type;
const networkSubType = router.query.network_sub_type;
React.useEffect(() => {
if (typeof networkType === 'string') {
cookies.set(cookies.NAMES.NETWORK_TYPE, networkType);
}
if (typeof networkSubType === 'string') {
cookies.set(cookies.NAMES.NETWORK_SUB_TYPE, networkSubType);
}
}, [ networkType, networkSubType ]);
return (
<Popover openDelay={ 300 } placement="right-start" gutter={ 22 } isLazy>
<PopoverTrigger>
<Button variant="unstyled" display="inline-flex" alignSelf="stretch" alignItems="center">
<Icon
as={ networksIcon }
width="16px"
height="16px"
color={ useColorModeValue('gray.500', 'gray.400') }
_hover={{ color: 'blue.400' }}
marginLeft={ isCollapsed ? '0px' : '27px' }
cursor="pointer"
{ ...getDefaultTransitionProps({ transitionProperty: 'margin' }) }
/>
</Button>
</PopoverTrigger>
<NetworkMenuPopup/>
</Popover>
);
};
export default React.memo(NetworkMenu);
import { Box, HStack, VStack } from '@chakra-ui/react'; import { Box, HStack, VStack } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import Header from 'ui/header/Header'; import * as cookies from 'lib/cookies';
import Navigation from 'ui/navigation/Navigation'; import useIsMobile from 'lib/hooks/useIsMobile';
import Header from 'ui/blocks/header/Header';
import NavigationDesktop from 'ui/blocks/navigation/NavigationDesktop';
interface Props { interface Props {
children: React.ReactNode; children: React.ReactNode;
} }
const Page = ({ children }: Props) => { const Page = ({ children }: Props) => {
const isMobile = useIsMobile();
const router = useRouter();
const networkType = router.query.network_type;
const networkSubType = router.query.network_sub_type;
React.useEffect(() => {
if (typeof networkType === 'string') {
cookies.set(cookies.NAMES.NETWORK_TYPE, networkType);
}
if (typeof networkSubType === 'string') {
cookies.set(cookies.NAMES.NETWORK_SUB_TYPE, networkSubType);
}
}, [ networkType, networkSubType ]);
return ( return (
<HStack <HStack
w="100%" w="100%"
minH="100vh" minH="100vh"
spacing={ 12 }
alignItems="stretch" alignItems="stretch"
paddingRight="60px"
> >
<Navigation/> { !isMobile && <NavigationDesktop/> }
<VStack width="100%"> <VStack width="100%" paddingX={ isMobile ? 4 : 8 } paddingTop={ isMobile ? 0 : 9 } paddingBottom={ 10 } spacing={ 0 }>
<Header/> <Header/>
<Box <Box
as="main" as="main"
borderRadius="base" borderRadius="base"
w="100%" w="100%"
overflow="hidden" overflow="hidden"
py={ 8 } paddingTop={ isMobile ? '138px' : '52px' }
> >
{ children } { children }
</Box> </Box>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment