From 6459e4fe49dd6f0bfdce1f471a139270fa665603 Mon Sep 17 00:00:00 2001 From: Fran Jimenez Aguilera Date: Sat, 12 Oct 2024 15:47:50 +0200 Subject: [PATCH 1/6] feat(web): add multiple prop to Dropdown --- apps/web/src/components/Dropdown/Option.tsx | 39 ++++++++++--------- apps/web/src/components/Dropdown/index.tsx | 42 +++++++++++++++++---- 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/apps/web/src/components/Dropdown/Option.tsx b/apps/web/src/components/Dropdown/Option.tsx index 91700e17..1d140055 100644 --- a/apps/web/src/components/Dropdown/Option.tsx +++ b/apps/web/src/components/Dropdown/Option.tsx @@ -1,28 +1,33 @@ import { ListboxOption } from "@headlessui/react"; +import { CheckIcon } from "@heroicons/react/24/outline"; -import type { Option as OptionProps } from "."; +import type { Option as OptionType } from "."; + +interface OptionProps { + option: OptionType; +} export const Option: React.FC = function (props) { - const { prefix, label, value } = props; + const { prefix, label, value } = props.option; return ( - `relative cursor-pointer select-none px-4 py-2 ${ - focus - ? "bg-controlActive-light dark:bg-controlActive-dark dark:text-content-dark" - : "text-contentSecondary-light dark:text-contentSecondary-dark" - }` - } - value={props} + className={`relative cursor-pointer select-none px-4 py-2 text-contentSecondary-light data-[selected]:bg-controlActive-light dark:text-contentSecondary-dark data-[selected]:dark:bg-controlActive-dark data-[selected]:dark:text-content-dark`} + value={props.option} > {({ selected }) => ( -
- {prefix && prefix} - - {label ? label : value} - +
+
+ {prefix && prefix} + + {label ? label : value} + +
+ {selected && ( +
)} diff --git a/apps/web/src/components/Dropdown/index.tsx b/apps/web/src/components/Dropdown/index.tsx index a6c8f572..59c72f06 100644 --- a/apps/web/src/components/Dropdown/index.tsx +++ b/apps/web/src/components/Dropdown/index.tsx @@ -1,3 +1,4 @@ +import { Fragment } from "react"; import type { ReactNode } from "react"; import { Listbox, @@ -13,28 +14,45 @@ export interface Option { value: string | number; label?: ReactNode; prefix?: ReactNode; + inputDisplay?: ReactNode; } -export interface DropdownProps { + +type BaseDropdownProps = { options: Option[]; - selected?: Option | null; width?: string; placeholder?: string; clearable?: boolean; +}; + +interface SingleDropdownProps extends BaseDropdownProps { + selected?: Option | null; + multiple?: false; onChange(newOption: Option | null): void; } +export interface MultiDropdownProps extends BaseDropdownProps { + selected?: Option[] | null; + multiple: true; + onChange(newOptions: Option[]): void; +} + +export type DropdownProps = SingleDropdownProps | MultiDropdownProps; + const DEFAULT_WIDTH = "w-32"; export const Dropdown: React.FC = function ({ options, selected, + multiple, width, onChange, clearable = false, placeholder = "Select an item", }) { + const hasValue = Array.isArray(selected) ? selected.length > 0 : selected; + return ( - +
= function ({ } flex cursor-pointer items-center justify-between rounded-lg border border-transparent bg-controlBackground-light pl-2 pr-8 text-left text-sm shadow-md hover:border hover:border-controlBorderHighlight-light focus:outline-none focus-visible:border-indigo-500 focus-visible:ring-2 focus-visible:ring-white active:border-controlBorderHighlight-dark ui-open:border-controlActive-light dark:bg-controlBackground-dark dark:hover:border-controlBorderHighlight-dark dark:ui-open:border-controlActive-dark`} >
- {selected ? ( - selected.label ?? selected.value + {hasValue ? ( + Array.isArray(selected) ? ( +
+ {selected.map((s) => { + return {s.inputDisplay}; + })} +
+ ) : ( + selected?.label + ) ) : (
{placeholder} @@ -51,12 +77,12 @@ export const Dropdown: React.FC = function ({ )}
- {clearable && selected ? ( + {clearable && hasValue ? ( { e.stopPropagation(); - onChange(null); + multiple ? onChange([]) : onChange(null); }} /> ) : ( @@ -74,7 +100,7 @@ export const Dropdown: React.FC = function ({ > {options.map((option, id) => ( - From 37c2fe27966f2bc42dd09c29dec0464114243d73 Mon Sep 17 00:00:00 2001 From: Fran Jimenez Aguilera Date: Sat, 12 Oct 2024 15:48:18 +0200 Subject: [PATCH 2/6] feat(web): add multi select prop to RollupFilter --- .../src/components/Filters/RollupFilter.tsx | 30 ++++++++------ apps/web/src/components/Filters/index.tsx | 41 +++++++++++-------- packages/api/src/middlewares/withFilters.ts | 2 +- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/apps/web/src/components/Filters/RollupFilter.tsx b/apps/web/src/components/Filters/RollupFilter.tsx index ca846675..ee8c63fd 100644 --- a/apps/web/src/components/Filters/RollupFilter.tsx +++ b/apps/web/src/components/Filters/RollupFilter.tsx @@ -3,14 +3,16 @@ import type { FC } from "react"; import { getChainRollups } from "@blobscan/rollups"; import { Dropdown } from "~/components/Dropdown"; -import type { DropdownProps, Option } from "~/components/Dropdown"; +import type { Option } from "~/components/Dropdown"; import { RollupIcon } from "~/components/RollupIcon"; import { env } from "~/env.mjs"; import type { Rollup } from "~/types"; import { capitalize, getChainIdByName } from "~/utils"; +import { RollupBadge } from "../Badges/RollupBadge"; -type RollupFilterProps = Pick & { - onChange(newRollup: Option | null): void; +type RollupFilterProps = { + onChange(newRollup: Option[]): void; + selected: Option[] | null; }; const chainId = getChainIdByName(env.NEXT_PUBLIC_NETWORK_NAME); @@ -21,15 +23,16 @@ export const ROLLUP_OPTIONS: Option[] = [ value: "null", label: "None", }, - ...rollups.map(([rollupAddress, rollupName]) => ({ - value: rollupAddress, - label: ( -
- - {capitalize(rollupName)} -
- ), - })), + ...rollups.map(([rollupAddress, rollupName]) => { + return { + value: rollupAddress, + inputDisplay: ( + + ), + prefix: , + label: capitalize(rollupName), + }; + }), ]; export const RollupFilter: FC = function ({ @@ -41,8 +44,9 @@ export const RollupFilter: FC = function ({ selected={selected} options={ROLLUP_OPTIONS} onChange={onChange} + multiple={true} placeholder="Rollup" - width="sm:w-[130px] w-full md:max-lg:w-full" + width="sm:w-[130px] w-full xl:w-[240px] md:max-lg:w-full" clearable /> ); diff --git a/apps/web/src/components/Filters/index.tsx b/apps/web/src/components/Filters/index.tsx index 4a52cb80..a56f0045 100644 --- a/apps/web/src/components/Filters/index.tsx +++ b/apps/web/src/components/Filters/index.tsx @@ -17,8 +17,10 @@ import { SlotFilter } from "./SlotFilter"; import { SortToggle } from "./SortToggle"; import { TimestampFilter } from "./TimestampFilter"; +const FROM_ADDRESSES_FORMAT_SEPARATOR = ","; + type FiltersState = { - rollup: Option | null; + rollups: Option[] | null; timestampRange: DateRangeType | null; blockNumberRange: NumberRange | null; slotRange: NumberRange | null; @@ -40,7 +42,7 @@ type FiltersAction = | UpdateAction; const INIT_STATE: FiltersState = { - rollup: null, + rollups: [], timestampRange: { endDate: null, startDate: null, @@ -75,7 +77,7 @@ export const Filters: FC = function () { const queryParams = useQueryParams(); const [filters, dispatch] = useReducer(reducer, INIT_STATE); const disableClear = - !filters.rollup && + !filters.rollups && !filters.timestampRange?.endDate && !filters.timestampRange?.startDate && !filters.blockNumberRange && @@ -84,14 +86,16 @@ export const Filters: FC = function () { const handleFilter = () => { const query: UrlObject["query"] = {}; - const { rollup, timestampRange, blockNumberRange, slotRange, sort } = + const { rollups, timestampRange, blockNumberRange, slotRange, sort } = filters; - if (rollup) { - if (rollup.value === "null") { - query.rollup = rollup.value; + if (rollups && rollups.length > 0) { + if (rollups.length === 1 && rollups[0]?.value === "null") { + query.rollup = rollups[0]?.value; } else { - query.from = rollup.value; + query.from = rollups + .map((r) => r.value) + .join(FROM_ADDRESSES_FORMAT_SEPARATOR); } } @@ -156,12 +160,15 @@ export const Filters: FC = function () { const newFilters: Partial = {}; if (rollup || from) { - const rollupOption = ROLLUP_OPTIONS.find( - (opt) => opt.value === rollup || opt.value === from - ); + const rollupOptions = ROLLUP_OPTIONS.filter((opt) => { + const fromAddresses = from?.split(FROM_ADDRESSES_FORMAT_SEPARATOR); + return ( + opt.value === rollup || fromAddresses?.includes(opt.value as string) + ); + }); - if (rollupOption) { - newFilters.rollup = rollupOption; + if (rollupOptions) { + newFilters.rollups = rollupOptions; } } @@ -204,11 +211,11 @@ export const Filters: FC = function () { dispatch({ type: "UPDATE", payload: { sort: newSort } }); }} /> -
+
- dispatch({ type: "UPDATE", payload: { rollup: newRollup } }) + selected={filters.rollups} + onChange={(newRollups) => + dispatch({ type: "UPDATE", payload: { rollups: newRollups } }) } />
diff --git a/packages/api/src/middlewares/withFilters.ts b/packages/api/src/middlewares/withFilters.ts index 3f2acd1d..3d41f9e0 100644 --- a/packages/api/src/middlewares/withFilters.ts +++ b/packages/api/src/middlewares/withFilters.ts @@ -155,7 +155,7 @@ export const withFilters = t.middleware(({ next, input = {} }) => { filters.transactionAddresses = []; if (from) { filters.transactionAddresses.push({ - fromId: from, + fromId: { in: from.split(",") }, }); } From e366a7f3c1d0e16a3d124193c20d4c36e26725ea Mon Sep 17 00:00:00 2001 From: Fran Jimenez Aguilera Date: Sat, 12 Oct 2024 16:21:55 +0200 Subject: [PATCH 3/6] fix(web): add check in RollupFilter to make none option unique --- apps/web/src/components/Dropdown/index.tsx | 6 +++- .../src/components/Filters/RollupFilter.tsx | 30 +++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/apps/web/src/components/Dropdown/index.tsx b/apps/web/src/components/Dropdown/index.tsx index 59c72f06..dc0e49c2 100644 --- a/apps/web/src/components/Dropdown/index.tsx +++ b/apps/web/src/components/Dropdown/index.tsx @@ -64,7 +64,11 @@ export const Dropdown: React.FC = function ({ Array.isArray(selected) ? (
{selected.map((s) => { - return {s.inputDisplay}; + return ( + + {s.inputDisplay ? s.inputDisplay : s.label} + + ); })}
) : ( diff --git a/apps/web/src/components/Filters/RollupFilter.tsx b/apps/web/src/components/Filters/RollupFilter.tsx index ee8c63fd..153b6747 100644 --- a/apps/web/src/components/Filters/RollupFilter.tsx +++ b/apps/web/src/components/Filters/RollupFilter.tsx @@ -1,3 +1,4 @@ +import { useRef } from "react"; import type { FC } from "react"; import { getChainRollups } from "@blobscan/rollups"; @@ -8,10 +9,11 @@ import { RollupIcon } from "~/components/RollupIcon"; import { env } from "~/env.mjs"; import type { Rollup } from "~/types"; import { capitalize, getChainIdByName } from "~/utils"; +import { Badge } from "../Badges/Badge"; import { RollupBadge } from "../Badges/RollupBadge"; type RollupFilterProps = { - onChange(newRollup: Option[]): void; + onChange(newRollups: Option[]): void; selected: Option[] | null; }; @@ -21,6 +23,7 @@ const rollups = chainId ? getChainRollups(chainId) : []; export const ROLLUP_OPTIONS: Option[] = [ { value: "null", + inputDisplay: None, label: "None", }, ...rollups.map(([rollupAddress, rollupName]) => { @@ -39,11 +42,34 @@ export const RollupFilter: FC = function ({ onChange, selected, }) { + const noneIsSelected = useRef(false); + + const handleOnChange = (newRollups_: Option[]) => { + let newRollups = newRollups_; + const noneOptionIndex = newRollups.findIndex((r) => r.value === "null"); + + if (noneIsSelected.current && newRollups.length > 1) { + noneIsSelected.current = false; + newRollups = newRollups.filter((_, index) => index !== noneOptionIndex); + } + + if ( + !noneIsSelected.current && + noneOptionIndex !== -1 && + newRollups.length > 1 + ) { + noneIsSelected.current = true; + newRollups = newRollups.filter((_, index) => index === noneOptionIndex); + } + + onChange(newRollups); + }; + return ( Date: Sat, 12 Oct 2024 19:59:56 +0200 Subject: [PATCH 4/6] fix(web): add a linear opacity gradient to RollupFilter overflow --- apps/web/package.json | 1 + apps/web/src/components/Dropdown/index.tsx | 20 ++++++++++++--- apps/web/src/hooks/useOverflow.ts | 29 ++++++++++++++++++++++ pnpm-lock.yaml | 20 +++++++-------- tooling/tailwind/index.ts | 6 ++++- 5 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 apps/web/src/hooks/useOverflow.ts diff --git a/apps/web/package.json b/apps/web/package.json index ea1b85aa..c54c3fba 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -55,6 +55,7 @@ "react-loading-skeleton": "^3.3.1", "react-tailwindcss-datepicker": "^1.6.6", "superjson": "1.9.1", + "tailwind-gradient-mask-image": "^1.2.0", "tailwind-merge": "^2.4.0", "viem": "^2.17.4", "zod": "^3.21.4" diff --git a/apps/web/src/components/Dropdown/index.tsx b/apps/web/src/components/Dropdown/index.tsx index dc0e49c2..35bd668b 100644 --- a/apps/web/src/components/Dropdown/index.tsx +++ b/apps/web/src/components/Dropdown/index.tsx @@ -1,4 +1,4 @@ -import { Fragment } from "react"; +import { Fragment, useRef } from "react"; import type { ReactNode } from "react"; import { Listbox, @@ -7,7 +7,9 @@ import { Transition, } from "@headlessui/react"; import { ChevronUpDownIcon, XMarkIcon } from "@heroicons/react/24/solid"; +import cn from "classnames"; +import useOverflow from "~/hooks/useOverflow"; import { Option } from "./Option"; export interface Option { @@ -51,6 +53,10 @@ export const Dropdown: React.FC = function ({ }) { const hasValue = Array.isArray(selected) ? selected.length > 0 : selected; + const containerRef = useRef(null); + const innerRef = useRef(null); + const isOverflowing = useOverflow(containerRef, innerRef); + return (
@@ -59,10 +65,18 @@ export const Dropdown: React.FC = function ({ width ?? DEFAULT_WIDTH } flex cursor-pointer items-center justify-between rounded-lg border border-transparent bg-controlBackground-light pl-2 pr-8 text-left text-sm shadow-md hover:border hover:border-controlBorderHighlight-light focus:outline-none focus-visible:border-indigo-500 focus-visible:ring-2 focus-visible:ring-white active:border-controlBorderHighlight-dark ui-open:border-controlActive-light dark:bg-controlBackground-dark dark:hover:border-controlBorderHighlight-dark dark:ui-open:border-controlActive-dark`} > -
+
{hasValue ? ( Array.isArray(selected) ? ( -
+
{selected.map((s) => { return ( diff --git a/apps/web/src/hooks/useOverflow.ts b/apps/web/src/hooks/useOverflow.ts new file mode 100644 index 00000000..84298b38 --- /dev/null +++ b/apps/web/src/hooks/useOverflow.ts @@ -0,0 +1,29 @@ +import { useEffect, useState } from "react"; + +const useOverflow = ( + containerRef: React.RefObject, + innerRef: React.RefObject +) => { + const [isOverflowing, setIsOverflowing] = useState(false); + + useEffect(() => { + const container = containerRef.current; + const inner = innerRef.current; + + if (!container || !inner) return; + + const resizeObserver = new ResizeObserver(() => { + setIsOverflowing(inner.scrollWidth > container.clientWidth); + }); + + resizeObserver.observe(inner); + + return () => { + resizeObserver.disconnect(); + }; + }, [containerRef, innerRef]); + + return isOverflowing; +}; + +export default useOverflow; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 65d553c3..4b374521 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -112,7 +112,7 @@ importers: version: 0.5.13(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) autoprefixer: specifier: ^10.4.14 - version: 10.4.19(postcss@8.4.38) + version: 10.4.19(postcss@8.4.39) clsx: specifier: ^2.1.0 version: 2.1.1 @@ -352,6 +352,9 @@ importers: superjson: specifier: 1.9.1 version: 1.9.1 + tailwind-gradient-mask-image: + specifier: ^1.2.0 + version: 1.2.0 tailwind-merge: specifier: ^2.4.0 version: 2.4.0 @@ -6501,6 +6504,9 @@ packages: resolution: {integrity: sha512-AfbFMOsAZDoaQq2sDF/F7PSTxnTBexr4cuArFW1bMl07tFbB+HBwKpnw99To3ffcjRFe12dEoyckiNz1+qCSng==} engines: {node: '>=12.17'} + tailwind-gradient-mask-image@1.2.0: + resolution: {integrity: sha512-tUJaGhvqbJFiVKJu6EU5n//KvGdVvY3L3VOFNqjztk13+ifAk00pcSNHBTgHfUiBGOEzDn0gFRbSmsftUV1lXA==} + tailwind-merge@2.4.0: resolution: {integrity: sha512-49AwoOQNKdqKPd9CViyH5wJoSKsCDjUlzL8DxuGp3P1FsGY36NJDAa18jLZcaHAUUuTj+JB8IAo8zWgBNvBF7A==} @@ -10366,16 +10372,6 @@ snapshots: asynckit@0.4.0: {} - autoprefixer@10.4.19(postcss@8.4.38): - dependencies: - browserslist: 4.23.0 - caniuse-lite: 1.0.30001614 - fraction.js: 4.3.7 - normalize-range: 0.1.2 - picocolors: 1.0.0 - postcss: 8.4.38 - postcss-value-parser: 4.2.0 - autoprefixer@10.4.19(postcss@8.4.39): dependencies: browserslist: 4.23.0 @@ -13771,6 +13767,8 @@ snapshots: array-back: 6.2.2 wordwrapjs: 5.1.0 + tailwind-gradient-mask-image@1.2.0: {} + tailwind-merge@2.4.0: {} tailwindcss@3.4.6(ts-node@10.9.2(@types/node@18.19.41)(typescript@5.5.3)): diff --git a/tooling/tailwind/index.ts b/tooling/tailwind/index.ts index 7e318d31..b7638d12 100644 --- a/tooling/tailwind/index.ts +++ b/tooling/tailwind/index.ts @@ -17,5 +17,9 @@ export default { }, }, }, - plugins: [require("@tailwindcss/forms"), require("@headlessui/tailwindcss")], + plugins: [ + require("@tailwindcss/forms"), + require("@headlessui/tailwindcss"), + require("tailwind-gradient-mask-image"), + ], } satisfies Config; From 2d9fa4ca4b8195889579ae9652d4da190f897ae7 Mon Sep 17 00:00:00 2001 From: Fran Jimenez Aguilera Date: Sat, 12 Oct 2024 20:04:47 +0200 Subject: [PATCH 5/6] chore(web): update changeset --- .changeset/old-pianos-help.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/old-pianos-help.md diff --git a/.changeset/old-pianos-help.md b/.changeset/old-pianos-help.md new file mode 100644 index 00000000..86d01ede --- /dev/null +++ b/.changeset/old-pianos-help.md @@ -0,0 +1,5 @@ +--- +"@blobscan/web": minor +--- + +Added multiple options to RollupFilter From a6796f2ec3e737111e8386656a45f219f0f2f3e5 Mon Sep 17 00:00:00 2001 From: Fran Jimenez Aguilera Date: Sun, 13 Oct 2024 12:33:42 +0200 Subject: [PATCH 6/6] fix(web): simplify Dropdown multiple props strategy --- apps/web/src/components/Dropdown/index.tsx | 23 ++++++------------- .../src/components/Filters/RollupFilter.tsx | 2 +- .../Layouts/PaginatedListLayout.tsx | 5 ++-- .../src/components/PaginatedTable/index.tsx | 4 ++-- apps/web/src/pages/blob/[hash].tsx | 4 ++-- apps/web/src/pages/stats/index.tsx | 5 ++-- 6 files changed, 18 insertions(+), 25 deletions(-) diff --git a/apps/web/src/components/Dropdown/index.tsx b/apps/web/src/components/Dropdown/index.tsx index 35bd668b..949861b6 100644 --- a/apps/web/src/components/Dropdown/index.tsx +++ b/apps/web/src/components/Dropdown/index.tsx @@ -19,27 +19,16 @@ export interface Option { inputDisplay?: ReactNode; } -type BaseDropdownProps = { +export interface DropdownProps { options: Option[]; width?: string; placeholder?: string; clearable?: boolean; -}; - -interface SingleDropdownProps extends BaseDropdownProps { - selected?: Option | null; - multiple?: false; - onChange(newOption: Option | null): void; + selected?: Option | Option[] | null; + multiple?: boolean; + onChange(newOption: Option | Option[] | null): void; } -export interface MultiDropdownProps extends BaseDropdownProps { - selected?: Option[] | null; - multiple: true; - onChange(newOptions: Option[]): void; -} - -export type DropdownProps = SingleDropdownProps | MultiDropdownProps; - const DEFAULT_WIDTH = "w-32"; export const Dropdown: React.FC = function ({ @@ -85,8 +74,10 @@ export const Dropdown: React.FC = function ({ ); })}
+ ) : selected?.label ? ( + selected.label ) : ( - selected?.label + selected?.value ) ) : (
diff --git a/apps/web/src/components/Filters/RollupFilter.tsx b/apps/web/src/components/Filters/RollupFilter.tsx index 153b6747..68180d0a 100644 --- a/apps/web/src/components/Filters/RollupFilter.tsx +++ b/apps/web/src/components/Filters/RollupFilter.tsx @@ -70,10 +70,10 @@ export const RollupFilter: FC = function ({ selected={selected} options={ROLLUP_OPTIONS} onChange={handleOnChange} - multiple={true} placeholder="Rollup" width="sm:w-[130px] w-full xl:w-[240px] md:max-lg:w-full" clearable + multiple /> ); }; diff --git a/apps/web/src/components/Layouts/PaginatedListLayout.tsx b/apps/web/src/components/Layouts/PaginatedListLayout.tsx index 5acddeee..20fad082 100644 --- a/apps/web/src/components/Layouts/PaginatedListLayout.tsx +++ b/apps/web/src/components/Layouts/PaginatedListLayout.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/router"; import { Header } from "~/components/Header"; import { Card } from "../Cards/Card"; import { Dropdown } from "../Dropdown"; -import type { DropdownProps } from "../Dropdown"; +import type { DropdownProps, Option } from "../Dropdown"; import { Pagination } from "../Pagination"; import type { PaginationProps } from "../Pagination"; @@ -47,7 +47,7 @@ export const PaginatedListLayout: FC = function ({ const hasItems = !items || items.length; const handlePageSizeSelection = useCallback( - (option) => { + (option: Option) => { if (!option) { return; } @@ -126,6 +126,7 @@ export const PaginatedListLayout: FC = function ({
Displayed items: = function ({ : undefined; const handlePageSizeSelection = useCallback( - (option) => { + (option: Option) => { if (!option) { return; } diff --git a/apps/web/src/pages/blob/[hash].tsx b/apps/web/src/pages/blob/[hash].tsx index f708de73..ff3ffb16 100644 --- a/apps/web/src/pages/blob/[hash].tsx +++ b/apps/web/src/pages/blob/[hash].tsx @@ -13,7 +13,7 @@ import type { BlobViewMode } from "~/components/BlobViewer"; import { Card } from "~/components/Cards/Card"; import { Copyable, CopyToClipboard } from "~/components/CopyToClipboard"; import { Dropdown } from "~/components/Dropdown"; -import type { DropdownProps } from "~/components/Dropdown"; +import type { DropdownProps, Option } from "~/components/Dropdown"; import type { DetailsLayoutProps } from "~/components/Layouts/DetailsLayout"; import { DetailsLayout } from "~/components/Layouts/DetailsLayout"; import { Link } from "~/components/Link"; @@ -187,7 +187,7 @@ const Blob: NextPage = function () { value: selectedBlobViewMode, label: selectedBlobViewMode, }} - onChange={(option) => + onChange={(option: Option) => option ? setSelectedBlobViewMode(option.value as BlobViewMode) : undefined diff --git a/apps/web/src/pages/stats/index.tsx b/apps/web/src/pages/stats/index.tsx index 7f4cb053..f156e674 100644 --- a/apps/web/src/pages/stats/index.tsx +++ b/apps/web/src/pages/stats/index.tsx @@ -19,6 +19,7 @@ import { DailyTransactionsChart, DailyUniqueAddressesChart, } from "~/components/Charts/Transaction"; +import type { Option } from "~/components/Dropdown"; import { Dropdown } from "~/components/Dropdown"; import { Header } from "~/components/Header"; import { api } from "~/api-client"; @@ -218,7 +219,7 @@ function Charts() { width="w-48" options={SECTIONS} selected={SECTIONS.find((option) => option.value === sectionFilter)} - onChange={(option) => { + onChange={(option: Option) => { if (!option) return; setSectionFilter(option.value as Section); }} @@ -226,7 +227,7 @@ function Charts() { option.value === timeFrame)} - onChange={(option) => { + onChange={(option: Option) => { if (!option) return; setTimeFrame(option.value as TimeFrame); }}