Skip to content

Commit be50b8b

Browse files
committed
search input touchups
1 parent 5838993 commit be50b8b

File tree

4 files changed

+81
-28
lines changed

4 files changed

+81
-28
lines changed

packages/sandcastle/src/Gallery.css

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,28 @@
1616
h2 {
1717
font-size: large;
1818
}
19+
20+
.search-input {
21+
/* Button width + padding on each side of it */
22+
padding-inline-end: calc(16px + 2 * 4px);
23+
}
24+
25+
.clear-btn {
26+
position: absolute;
27+
right: 4px;
28+
padding: 2px;
29+
min-block-size: unset;
30+
31+
svg {
32+
width: 12px;
33+
height: 12px;
34+
}
35+
}
36+
37+
.tag-select {
38+
/* This helps prevent needing to resize when tags load */
39+
min-width: 140px;
40+
}
1941
}
2042

2143
.list {

packages/sandcastle/src/Gallery.tsx

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { useEffect, useMemo, useRef, useState } from "react";
22
import "./Gallery.css";
3-
import { Badge, Button, IconButton, Select } from "@stratakit/bricks";
3+
import { Badge, IconButton, Select, Spinner, TextBox } from "@stratakit/bricks";
44
import { getBaseUrl } from "./util/getBaseUrl";
5-
import { Input } from "@stratakit/bricks/TextBox";
65
import classNames from "classnames";
7-
import { script } from "./icons";
6+
import { close, script, search } from "./icons";
7+
import { ProcessStatus } from "./util/ProcessStatus";
88

99
const GALLERY_BASE = __GALLERY_BASE_URL__;
1010

@@ -32,6 +32,7 @@ export function GallerySearch({
3232

3333
const [searchTerm, setSearchTerm] = useState("");
3434
const [currentTag, setCurrentTag] = useState<string | "All">("All");
35+
const [searchState, setSearchState] = useState<ProcessStatus>("NOT_STARTED");
3536

3637
const requestId = useRef<number>(0);
3738

@@ -40,9 +41,12 @@ export function GallerySearch({
4041
if (!pagefind.current) {
4142
return;
4243
}
44+
45+
setSearchState("IN_PROGRESS");
4346
const searchString = searchTerm;
4447
if (!searchString || searchString === "") {
4548
setSearchResults(null);
49+
setSearchState("COMPLETE");
4650
return;
4751
}
4852
const thisRequestId = ++requestId.current;
@@ -66,6 +70,7 @@ export function GallerySearch({
6670

6771
if (thisRequestId === requestId.current) {
6872
setSearchResults(resultData);
73+
setSearchState("COMPLETE");
6974
}
7075
}
7176

@@ -104,35 +109,49 @@ export function GallerySearch({
104109

105110
return (
106111
<>
107-
{!!searchTerm && (
108-
<Button
109-
onClick={() => {
110-
setSearchTerm("");
111-
if (inputRef.current) {
112-
inputRef.current.value = "";
112+
{searchState === "IN_PROGRESS" && <Spinner />}
113+
<TextBox.Root className="search-input">
114+
<TextBox.Icon href={search} />
115+
<TextBox.Input
116+
ref={inputRef}
117+
disabled={!pagefindLoaded}
118+
onChange={(e) => {
119+
if (debounceTimeout.current) {
120+
clearInterval(debounceTimeout.current);
113121
}
122+
const newSearchTerm = e.target.value;
123+
pagefind.current?.preload(newSearchTerm);
124+
if (newSearchTerm === "") {
125+
// Instantly update for a more reactive feel when clearing the input
126+
console.log("early clear");
127+
setSearchTerm("");
128+
return;
129+
}
130+
debounceTimeout.current = setTimeout(() => {
131+
setSearchTerm(newSearchTerm);
132+
}, 300);
114133
}}
115-
>
116-
Clear
117-
</Button>
118-
)}
119-
<Input
120-
ref={inputRef}
121-
disabled={!pagefindLoaded}
122-
onChange={(e) => {
123-
if (debounceTimeout.current) {
124-
clearInterval(debounceTimeout.current);
125-
}
126-
const newSearchTerm = e.target.value;
127-
pagefind.current?.preload(newSearchTerm);
128-
debounceTimeout.current = setTimeout(() => {
129-
setSearchTerm(newSearchTerm);
130-
}, 300);
131-
}}
132-
placeholder="Filter demos..."
133-
/>
134+
placeholder="Search gallery"
135+
/>
136+
{!!searchTerm && (
137+
<IconButton
138+
className="clear-btn"
139+
icon={close}
140+
label="Clear"
141+
onClick={(e) => {
142+
console.log(e);
143+
setSearchTerm("");
144+
if (inputRef.current) {
145+
inputRef.current.value = "";
146+
inputRef.current.focus();
147+
}
148+
}}
149+
></IconButton>
150+
)}
151+
</TextBox.Root>
134152
<Select.Root>
135153
<Select.HtmlSelect
154+
className="tag-select"
136155
disabled={!pagefindLoaded}
137156
onChange={(e) => {
138157
setCurrentTag(e.target.value);

packages/sandcastle/src/icons.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import image from "@stratakit/icons/image.svg";
1212
import windowPopout from "@stratakit/icons/window-popout.svg";
1313
import play from "@stratakit/icons/play.svg";
1414
import textAlignLeft from "@stratakit/icons/text-align-left.svg";
15+
import search from "@stratakit/icons/search.svg";
16+
import close from "@stratakit/icons/close.svg";
1517

1618
export {
1719
add,
@@ -28,4 +30,6 @@ export {
2830
windowPopout,
2931
play,
3032
textAlignLeft,
33+
search,
34+
close,
3135
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* Set of states that typically apply to a variety of processes
3+
*/
4+
export type ProcessStatus =
5+
| "NOT_STARTED"
6+
| "IN_PROGRESS"
7+
| "COMPLETE"
8+
| "ERROR";

0 commit comments

Comments
 (0)