Skip to content

Commit 90c8335

Browse files
authored
Merge pull request #3004 from pyth-network/feat/search-button-component
feat: search button component
2 parents d7cc062 + e93a4fd commit 90c8335

File tree

7 files changed

+137
-58
lines changed

7 files changed

+137
-58
lines changed

apps/developer-hub/src/components/search-button.tsx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
11
"use client";
22

3-
import { MagnifyingGlass } from "@phosphor-icons/react/dist/ssr/MagnifyingGlass";
4-
import { Button } from "@pythnetwork/component-library/Button";
3+
import { SearchButton as SearchButtonComponent } from "@pythnetwork/component-library/SearchButton";
54
import DefaultSearchDialog from "fumadocs-ui/components/dialog/search-default";
6-
import { useState } from "react";
5+
import { useCallback, useState } from "react";
76

87
export const SearchButton = () => {
98
const [open, setOpen] = useState(false);
109

10+
const handleSearch = useCallback(() => {
11+
setOpen(true);
12+
}, []);
13+
1114
return (
1215
<>
13-
<Button
14-
onClick={() => {
15-
setOpen(true);
16-
}}
17-
variant="outline"
16+
<SearchButtonComponent
1817
size="sm"
19-
rounded
20-
beforeIcon={<MagnifyingGlass size={16} />}
21-
>
22-
Search
23-
</Button>
18+
smallScreenContent="Search"
19+
largeScreenContent="Search"
20+
onClick={handleSearch}
21+
/>
2422
<DefaultSearchDialog
2523
open={open}
2624
onOpenChange={setOpen}

apps/insights/src/cache.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ const transformer = {
1212
// export const DEFAULT_CACHE_TTL = 3600; // 1 hour
1313
// export const DEFAULT_CACHE_STALE = 86_400; // 24 hours
1414

15-
1615
export const DEFAULT_CACHE_TTL = 60; // 1 minute
1716
export const DEFAULT_CACHE_STALE = 60; // 1 minute
1817

apps/insights/src/components/Root/search-button.module.scss

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,5 @@
11
@use "@pythnetwork/component-library/theme";
22

3-
.searchButton {
4-
.largeScreenSearchButton {
5-
display: none;
6-
7-
@include theme.breakpoint("md") {
8-
display: inline-flex;
9-
}
10-
}
11-
12-
.smallScreenSearchButton {
13-
@include theme.breakpoint("md") {
14-
display: none;
15-
}
16-
}
17-
}
18-
193
.searchDialogContents {
204
gap: theme.spacing(1);
215
display: flex;

apps/insights/src/components/Root/search-button.tsx

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
"use client";
22

3-
import { MagnifyingGlass } from "@phosphor-icons/react/dist/ssr/MagnifyingGlass";
43
import { XCircle } from "@phosphor-icons/react/dist/ssr/XCircle";
54
import { Badge } from "@pythnetwork/component-library/Badge";
65
import type { Props as ButtonProps } from "@pythnetwork/component-library/Button";
76
import { Button } from "@pythnetwork/component-library/Button";
87
import { NoResults } from "@pythnetwork/component-library/NoResults";
8+
import { SearchButton as SearchButtonComponent } from "@pythnetwork/component-library/SearchButton";
99
import { SearchInput } from "@pythnetwork/component-library/SearchInput";
1010
import { SingleToggleGroup } from "@pythnetwork/component-library/SingleToggleGroup";
1111
import { Skeleton } from "@pythnetwork/component-library/Skeleton";
1212
import {
13-
Virtualizer,
1413
ListLayout,
14+
Virtualizer,
1515
} from "@pythnetwork/component-library/Virtualizer";
1616
import type { Button as UnstyledButton } from "@pythnetwork/component-library/unstyled/Button";
1717
import {
@@ -21,15 +21,15 @@ import {
2121
import { useDrawer } from "@pythnetwork/component-library/useDrawer";
2222
import { useLogger } from "@pythnetwork/component-library/useLogger";
2323
import type { ReactNode } from "react";
24-
import { useMemo, useCallback, useEffect, useState } from "react";
25-
import { useIsSSR, useCollator, useFilter } from "react-aria";
24+
import { useCallback, useEffect, useMemo, useState } from "react";
25+
import { useCollator, useFilter, useIsSSR } from "react-aria";
2626

27-
import styles from "./search-button.module.scss";
2827
import { Cluster, ClusterToName } from "../../services/pyth";
2928
import { AssetClassBadge } from "../AssetClassBadge";
3029
import { PriceFeedTag } from "../PriceFeedTag";
3130
import { PublisherTag } from "../PublisherTag";
3231
import { Score } from "../Score";
32+
import styles from "./search-button.module.scss";
3333

3434
const INPUTS = new Set(["input", "select", "button", "textarea"]);
3535

@@ -73,29 +73,12 @@ const ResolvedSearchButton = (props: ResolvedSearchButtonProps) => {
7373
const SearchButtonImpl = (
7474
props: Omit<ButtonProps<typeof UnstyledButton>, "children">,
7575
) => (
76-
<div className={styles.searchButton}>
77-
<Button
78-
className={styles.largeScreenSearchButton ?? ""}
79-
variant="outline"
80-
beforeIcon={<MagnifyingGlass />}
81-
size="sm"
82-
rounded
83-
{...props}
84-
>
85-
<SearchShortcutText />
86-
</Button>
87-
<Button
88-
className={styles.smallScreenSearchButton ?? ""}
89-
hideText
90-
variant="ghost"
91-
beforeIcon={<MagnifyingGlass />}
92-
size="sm"
93-
rounded
94-
{...props}
95-
>
96-
Search
97-
</Button>
98-
</div>
76+
<SearchButtonComponent
77+
size="sm"
78+
{...props}
79+
smallScreenContent={<SearchShortcutText />}
80+
largeScreenContent={<SearchShortcutText />}
81+
/>
9982
);
10083

10184
const useSearchDrawer = ({ feeds, publishers }: ResolvedSearchButtonProps) => {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
@use "../theme";
2+
3+
.searchButton {
4+
.largeScreenSearchButton {
5+
display: none;
6+
7+
@include theme.breakpoint("md") {
8+
display: inline-flex;
9+
}
10+
}
11+
12+
.smallScreenSearchButton {
13+
@include theme.breakpoint("md") {
14+
display: none;
15+
}
16+
}
17+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import * as icons from "@phosphor-icons/react/dist/ssr";
2+
import type { Meta, StoryObj } from "@storybook/react";
3+
4+
import { SearchButton as SearchButtonComponent } from "./index.jsx";
5+
import { SIZES } from "../Button/index.jsx";
6+
7+
const iconControl = {
8+
control: "select",
9+
options: Object.keys(icons),
10+
mapping: Object.fromEntries(
11+
Object.entries(icons).map(([iconName, Icon]) => [
12+
iconName,
13+
<Icon key={iconName} weights={new Map()} />,
14+
]),
15+
),
16+
} as const;
17+
18+
const meta = {
19+
component: SearchButtonComponent,
20+
argTypes: {
21+
size: {
22+
control: "inline-radio",
23+
options: SIZES,
24+
table: {
25+
category: "Variant",
26+
},
27+
},
28+
beforeIcon: {
29+
...iconControl,
30+
table: {
31+
category: "Contents",
32+
},
33+
},
34+
},
35+
} satisfies Meta<typeof SearchButtonComponent>;
36+
export default meta;
37+
38+
export const SearchButton = {
39+
args: {
40+
largeScreenContent: "Search",
41+
smallScreenContent: "Search",
42+
size: "sm",
43+
},
44+
} satisfies StoryObj<typeof SearchButtonComponent>;
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"use client";
2+
3+
import { MagnifyingGlass } from "@phosphor-icons/react/dist/ssr/MagnifyingGlass";
4+
import clsx from "clsx";
5+
import type { ReactNode } from "react";
6+
import { Button as BaseButton } from "react-aria-components";
7+
8+
import type { Props as ButtonProps } from "../Button";
9+
import { Button } from "../Button";
10+
import styles from "./index.module.scss";
11+
12+
type OwnProps = {
13+
largeScreenContent?: ReactNode;
14+
smallScreenContent?: ReactNode;
15+
};
16+
17+
type Props = Pick<
18+
ButtonProps<typeof BaseButton>,
19+
"beforeIcon" | "size" | "onClick" | "className" | "isPending"
20+
> &
21+
OwnProps;
22+
23+
export const SearchButton = ({
24+
beforeIcon,
25+
largeScreenContent,
26+
smallScreenContent,
27+
...props
28+
}: Props) => {
29+
return (
30+
<div className={styles.searchButton}>
31+
<Button
32+
className={clsx(styles.largeScreenSearchButton, props.className)}
33+
variant="outline"
34+
beforeIcon={beforeIcon ?? <MagnifyingGlass />}
35+
size="sm"
36+
rounded
37+
{...props}
38+
>
39+
{largeScreenContent}
40+
</Button>
41+
<Button
42+
className={clsx(styles.smallScreenSearchButton, props.className)}
43+
hideText
44+
variant="ghost"
45+
beforeIcon={beforeIcon ?? <MagnifyingGlass />}
46+
size="sm"
47+
rounded
48+
{...props}
49+
>
50+
{smallScreenContent}
51+
</Button>
52+
</div>
53+
);
54+
};

0 commit comments

Comments
 (0)