Skip to content

Commit 0386e59

Browse files
committed
fix: add files back
1 parent c562163 commit 0386e59

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import type { Meta, StoryObj } from "@storybook/react-vite";
2+
import { Search, SearchInput } from "./Search";
3+
4+
const meta: Meta<typeof SearchInput> = {
5+
title: "components/Search",
6+
component: SearchInput,
7+
decorators: [
8+
(Story) => (
9+
<Search>
10+
<Story />
11+
</Search>
12+
),
13+
],
14+
};
15+
16+
export default meta;
17+
type Story = StoryObj<typeof SearchInput>;
18+
19+
export const Example: Story = {};
20+
21+
export const WithPlaceholder: Story = {
22+
args: {
23+
label: "uwu",
24+
placeholder: "uwu",
25+
},
26+
};

site/src/components/Search/Search.tsx

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// biome-ignore lint/style/noRestrictedImports: use it to have the component prop
2+
import type { Interpolation } from "@emotion/react";
3+
import type { Theme } from "@mui/material";
4+
import Box, { type BoxProps } from "@mui/material/Box";
5+
import visuallyHidden from "@mui/utils/visuallyHidden";
6+
import { SearchIcon } from "lucide-react";
7+
import type { FC, HTMLAttributes, InputHTMLAttributes, Ref } from "react";
8+
9+
interface SearchProps extends Omit<BoxProps, "ref"> {
10+
$$ref?: Ref<unknown>;
11+
}
12+
13+
/**
14+
* A container component meant for `SearchInput`
15+
*
16+
* ```
17+
* <Search>
18+
* <SearchInput />
19+
* </Search>
20+
* ```
21+
*/
22+
export const Search: FC<SearchProps> = ({ children, $$ref, ...boxProps }) => {
23+
return (
24+
<Box ref={$$ref} {...boxProps} css={SearchStyles.container}>
25+
<SearchIcon className="size-icon-xs" css={SearchStyles.icon} />
26+
{children}
27+
</Box>
28+
);
29+
};
30+
31+
const SearchStyles = {
32+
container: (theme) => ({
33+
display: "flex",
34+
alignItems: "center",
35+
paddingLeft: 16,
36+
height: 40,
37+
borderBottom: `1px solid ${theme.palette.divider}`,
38+
}),
39+
40+
icon: (theme) => ({
41+
fontSize: 14,
42+
color: theme.palette.text.secondary,
43+
}),
44+
} satisfies Record<string, Interpolation<Theme>>;
45+
46+
type SearchInputProps = InputHTMLAttributes<HTMLInputElement> & {
47+
label?: string;
48+
$$ref?: Ref<HTMLInputElement>;
49+
};
50+
51+
export const SearchInput: FC<SearchInputProps> = ({
52+
label,
53+
$$ref,
54+
...inputProps
55+
}) => {
56+
return (
57+
<>
58+
<label css={{ ...visuallyHidden }} htmlFor={inputProps.id}>
59+
{label}
60+
</label>
61+
<input
62+
ref={$$ref}
63+
tabIndex={-1}
64+
type="text"
65+
placeholder="Search..."
66+
css={SearchInputStyles.input}
67+
{...inputProps}
68+
/>
69+
</>
70+
);
71+
};
72+
73+
const SearchInputStyles = {
74+
input: (theme) => ({
75+
color: "inherit",
76+
height: "100%",
77+
border: 0,
78+
background: "none",
79+
flex: 1,
80+
marginLeft: 16,
81+
outline: 0,
82+
"&::placeholder": {
83+
color: theme.palette.text.secondary,
84+
},
85+
}),
86+
} satisfies Record<string, Interpolation<Theme>>;
87+
88+
export const SearchEmpty: FC<HTMLAttributes<HTMLDivElement>> = ({
89+
children = "Not found",
90+
...props
91+
}) => {
92+
return (
93+
<div css={SearchEmptyStyles.empty} {...props}>
94+
{children}
95+
</div>
96+
);
97+
};
98+
99+
const SearchEmptyStyles = {
100+
empty: (theme) => ({
101+
fontSize: 13,
102+
color: theme.palette.text.secondary,
103+
textAlign: "center",
104+
paddingTop: 8,
105+
paddingBottom: 8,
106+
}),
107+
} satisfies Record<string, Interpolation<Theme>>;
108+
109+
/**
110+
* Reusable styles for consumers of the base components
111+
*/
112+
export const searchStyles = {
113+
content: {
114+
width: 320,
115+
padding: 0,
116+
borderRadius: 4,
117+
},
118+
} satisfies Record<string, Interpolation<Theme>>;

0 commit comments

Comments
 (0)