Skip to content

Commit 626c12c

Browse files
authored
Merge branch 'main' into matt-user/fix-script-highlighting
2 parents 639d5bf + 3d4b737 commit 626c12c

File tree

7 files changed

+2798
-3064
lines changed

7 files changed

+2798
-3064
lines changed

packages/app/src/systems/Core/components/Search/SearchForm.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import { styles } from './styles';
1010
type SearchFormProps = {
1111
className: string;
1212
autoFocus?: boolean;
13+
expandOnFocus?: boolean;
1314
};
1415

15-
export function SearchForm({ className, autoFocus }: SearchFormProps) {
16+
export function SearchForm({ className, autoFocus, expandOnFocus }: SearchFormProps) {
1617
const classes = styles();
1718
const [results, action] = useFormState(
1819
(_: SearchResult | null, formData: FormData) => {
@@ -29,6 +30,7 @@ export function SearchForm({ className, autoFocus }: SearchFormProps) {
2930
searchResult={results}
3031
autoFocus={autoFocus}
3132
onClear={onClear}
33+
expandOnFocus={expandOnFocus}
3234
/>
3335
</form>
3436
);

packages/app/src/systems/Core/components/Search/SearchInput.tsx

+146-101
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
VStack,
1515
useBreakpoints,
1616
Box,
17+
Text,
1718
} from '@fuels/ui';
1819
import { IconCheck, IconSearch, IconX } from '@tabler/icons-react';
1920
import NextLink from 'next/link';
@@ -34,6 +35,7 @@ type SearchDropdownProps = {
3435
searchValue: string;
3536
width: number;
3637
onSelectItem: () => void;
38+
isExpanded?: boolean;
3739
};
3840

3941
const SearchResultDropdown = forwardRef<HTMLDivElement, SearchDropdownProps>(
@@ -45,6 +47,7 @@ const SearchResultDropdown = forwardRef<HTMLDivElement, SearchDropdownProps>(
4547
onOpenChange,
4648
width,
4749
onSelectItem,
50+
isExpanded,
4851
},
4952
ref,
5053
) => {
@@ -53,15 +56,25 @@ const SearchResultDropdown = forwardRef<HTMLDivElement, SearchDropdownProps>(
5356
const trimL = isMobile ? 15 : 20;
5457
const trimR = isMobile ? 13 : 18;
5558

59+
const hasResult =
60+
searchResult?.account ||
61+
searchResult?.block ||
62+
searchResult?.contract ||
63+
searchResult?.transaction;
64+
5665
return (
5766
<Dropdown open={openDropdown} onOpenChange={onOpenChange}>
5867
<Dropdown.Trigger>
5968
<Box className="w-full"></Box>
6069
</Dropdown.Trigger>
6170
<Dropdown.Content
6271
ref={ref}
63-
className={cx(classes.dropdownContent(), classes.searchSize())}
72+
className={cx(
73+
classes.dropdownContent(isExpanded),
74+
classes.searchSize(),
75+
)}
6476
style={{ width: width - 0.5 }}
77+
data-expanded={isExpanded}
6578
>
6679
{!searchResult && (
6780
<>
@@ -70,101 +83,116 @@ const SearchResultDropdown = forwardRef<HTMLDivElement, SearchDropdownProps>(
7083
</Dropdown.Item>
7184
</>
7285
)}
73-
{searchResult?.account && (
86+
{hasResult ? (
7487
<>
75-
<Dropdown.Label>Account</Dropdown.Label>
76-
<Dropdown.Item className={classes.dropdownItem()}>
77-
<Link
78-
as={NextLink}
79-
href={Routes.accountAssets(searchResult.account.address!)}
80-
className="text-color"
81-
onClick={onSelectItem}
82-
>
83-
{shortAddress(
84-
searchResult.account.address || '',
85-
trimL,
86-
trimR,
87-
)}
88-
</Link>
89-
</Dropdown.Item>
90-
<Dropdown.Separator />
91-
<Dropdown.Label>Recent Transactions</Dropdown.Label>
92-
{searchResult.account.transactions?.map((transaction) => {
93-
return (
94-
<Dropdown.Item
95-
key={transaction?.id}
96-
className={classes.dropdownItem()}
97-
>
88+
{searchResult?.account && (
89+
<>
90+
<Dropdown.Label>Account</Dropdown.Label>
91+
<Dropdown.Item className={classes.dropdownItem()}>
9892
<Link
9993
as={NextLink}
100-
href={Routes.txSimple(transaction!.id!)}
94+
href={Routes.accountAssets(searchResult.account.address!)}
10195
className="text-color"
10296
onClick={onSelectItem}
10397
>
104-
{shortAddress(transaction?.id || '', trimL, trimR)}
98+
{shortAddress(
99+
searchResult.account.address || '',
100+
trimL,
101+
trimR,
102+
)}
105103
</Link>
106104
</Dropdown.Item>
107-
);
108-
})}
109-
</>
110-
)}
111-
{searchResult?.block && (
112-
<>
113-
<Dropdown.Label>Block</Dropdown.Label>
114-
<Dropdown.Item className={classes.dropdownItem()}>
115-
<Link
116-
as={NextLink}
117-
href={Routes.blockSimple(searchResult.block.id!)}
118-
className="text-color"
119-
onClick={onSelectItem}
120-
>
121-
{shortAddress(searchResult.block.id || '', trimL, trimR)}
122-
</Link>
123-
</Dropdown.Item>
124-
<Dropdown.Item className={classes.dropdownItem()}>
125-
<Link
126-
as={NextLink}
127-
href={Routes.blockSimple(searchResult.block.height!)}
128-
className="text-color"
129-
onClick={onSelectItem}
130-
>
131-
{searchResult.block.height}
132-
</Link>
133-
</Dropdown.Item>
134-
</>
135-
)}
136-
{searchResult?.contract && (
137-
<>
138-
<Dropdown.Label>Contract</Dropdown.Label>
139-
<Dropdown.Item className={classes.dropdownItem()}>
140-
<Link
141-
as={NextLink}
142-
href={Routes.contractAssets(searchResult.contract.id!)}
143-
className="text-color"
144-
onClick={onSelectItem}
145-
>
146-
{shortAddress(searchResult.contract.id || '', trimL, trimR)}
147-
</Link>
148-
</Dropdown.Item>
105+
<Dropdown.Separator />
106+
<Dropdown.Label>Recent Transactions</Dropdown.Label>
107+
{searchResult.account.transactions?.map((transaction) => {
108+
return (
109+
<Dropdown.Item
110+
key={transaction?.id}
111+
className={classes.dropdownItem()}
112+
>
113+
<Link
114+
as={NextLink}
115+
href={Routes.txSimple(transaction!.id!)}
116+
className="text-color"
117+
onClick={onSelectItem}
118+
>
119+
{shortAddress(transaction?.id || '', trimL, trimR)}
120+
</Link>
121+
</Dropdown.Item>
122+
);
123+
})}
124+
</>
125+
)}
126+
{searchResult?.block && (
127+
<>
128+
<Dropdown.Label>Block</Dropdown.Label>
129+
<Dropdown.Item className={classes.dropdownItem()}>
130+
<Link
131+
as={NextLink}
132+
href={Routes.blockSimple(searchResult.block.id!)}
133+
className="text-color"
134+
onClick={onSelectItem}
135+
>
136+
{shortAddress(searchResult.block.id || '', trimL, trimR)}
137+
</Link>
138+
</Dropdown.Item>
139+
<Dropdown.Item className={classes.dropdownItem()}>
140+
<Link
141+
as={NextLink}
142+
href={Routes.blockSimple(searchResult.block.height!)}
143+
className="text-color"
144+
onClick={onSelectItem}
145+
>
146+
{searchResult.block.height}
147+
</Link>
148+
</Dropdown.Item>
149+
</>
150+
)}
151+
{searchResult?.contract && (
152+
<>
153+
<Dropdown.Label>Contract</Dropdown.Label>
154+
<Dropdown.Item className={classes.dropdownItem()}>
155+
<Link
156+
as={NextLink}
157+
href={Routes.contractAssets(searchResult.contract.id!)}
158+
className="text-color"
159+
onClick={onSelectItem}
160+
>
161+
{shortAddress(
162+
searchResult.contract.id || '',
163+
trimL,
164+
trimR,
165+
)}
166+
</Link>
167+
</Dropdown.Item>
168+
</>
169+
)}
170+
{searchResult?.transaction && (
171+
<>
172+
<Dropdown.Label>Transaction</Dropdown.Label>
173+
<Dropdown.Item className={classes.dropdownItem()}>
174+
<Link
175+
as={NextLink}
176+
href={Routes.txSimple(searchResult.transaction.id!)}
177+
className="text-color"
178+
onClick={onSelectItem}
179+
>
180+
{shortAddress(
181+
searchResult.transaction.id || '',
182+
trimL,
183+
trimR,
184+
)}
185+
</Link>
186+
</Dropdown.Item>
187+
</>
188+
)}
149189
</>
150-
)}
151-
{searchResult?.transaction && (
190+
) : (
152191
<>
153-
<Dropdown.Label>Transaction</Dropdown.Label>
154-
<Dropdown.Item className={classes.dropdownItem()}>
155-
<Link
156-
as={NextLink}
157-
href={Routes.txSimple(searchResult.transaction.id!)}
158-
className="text-color"
159-
onClick={onSelectItem}
160-
>
161-
{shortAddress(
162-
searchResult.transaction.id || '',
163-
trimL,
164-
trimR,
165-
)}
166-
</Link>
167-
</Dropdown.Item>
192+
<Dropdown.Label>No instances found for:</Dropdown.Label>
193+
<Text className="px-3 text-sm pb-1">
194+
&quot;{shortAddress(searchValue, trimL, trimR)}&quot;
195+
</Text>
168196
</>
169197
)}
170198
</Dropdown.Content>
@@ -178,6 +206,7 @@ type SearchInputProps = BaseProps<InputProps & InputFieldProps> & {
178206
onClear?: (value: string) => void;
179207
searchResult?: Maybe<SearchResult>;
180208
alwaysDisplayActionButtons?: boolean;
209+
expandOnFocus?: boolean;
181210
};
182211

183212
export function SearchInput({
@@ -187,12 +216,14 @@ export function SearchInput({
187216
autoFocus,
188217
placeholder = 'Search here...',
189218
searchResult,
219+
expandOnFocus,
190220
...props
191221
}: SearchInputProps) {
192222
const classes = styles();
193223
const [value, setValue] = useState<string>(initialValue as string);
194224
const [openDropdown, setOpenDropdown] = useState(false);
195225
const [hasSubmitted, setHasSubmitted] = useState(false);
226+
const [isExpanded, setIsExpanded] = useState(false);
196227
const inputRef = useRef<HTMLInputElement>(null);
197228
const inputWrapperRef = useRef<HTMLInputElement>(null);
198229
const { pending } = useFormStatus();
@@ -217,11 +248,21 @@ export function SearchInput({
217248
setValue('');
218249
setHasSubmitted(false);
219250
onClear?.(value);
220-
inputRef.current?.focus();
251+
if (isExpanded) {
252+
setIsExpanded(false);
253+
} else {
254+
inputRef.current?.focus();
255+
}
256+
}
257+
258+
function expandOnFocusHandler() {
259+
if (expandOnFocus) {
260+
setIsExpanded(true);
261+
}
221262
}
222263

223264
return (
224-
<VStack gap="0" className="justify-center items-center">
265+
<VStack gap="0" className={classes.searchBox()} data-expanded={isExpanded}>
225266
<Focus.ArrowNavigator autoFocus={autoFocus}>
226267
<Input
227268
ref={inputWrapperRef}
@@ -230,6 +271,7 @@ export function SearchInput({
230271
size="3"
231272
data-opened={openDropdown}
232273
className={cx(className, classes.inputWrapper())}
274+
onFocus={expandOnFocusHandler}
233275
onKeyDown={(e: KeyboardEvent<HTMLInputElement>) => {
234276
if (e.key === 'Enter') {
235277
e.preventDefault();
@@ -248,21 +290,23 @@ export function SearchInput({
248290
value={value}
249291
onChange={handleChange}
250292
/>
251-
{value?.length ? (
293+
{isExpanded || value?.length ? (
252294
<>
253295
<Input.Slot className="">
254-
<Tooltip content="Submit">
255-
<IconButton
256-
type="submit"
257-
aria-label="Submit"
258-
icon={IconCheck}
259-
iconColor="text-brand"
260-
variant="link"
261-
className="!ml-0 tablet:ml-2"
262-
isLoading={pending}
263-
onClick={handleSubmit}
264-
/>
265-
</Tooltip>
296+
{!!value?.length && (
297+
<Tooltip content="Submit">
298+
<IconButton
299+
type="submit"
300+
aria-label="Submit"
301+
icon={IconCheck}
302+
iconColor="text-brand"
303+
variant="link"
304+
className="!ml-0 tablet:ml-2"
305+
isLoading={pending}
306+
onClick={handleSubmit}
307+
/>
308+
</Tooltip>
309+
)}
266310
<IconButton
267311
aria-label="Clear"
268312
icon={IconX}
@@ -296,6 +340,7 @@ export function SearchInput({
296340
}
297341
setOpenDropdown(!openDropdown);
298342
}}
343+
isExpanded={isExpanded}
299344
/>
300345
</VStack>
301346
);

packages/app/src/systems/Core/components/Search/SearchWidget.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ type SearchWidgetProps = {
1414
autoFocus?: boolean;
1515
isSearchOpen: boolean;
1616
setIsSearchOpen: (value: boolean) => void;
17+
expandOnFocus?: boolean;
1718
};
1819

1920
export const SearchWidget = ({
2021
autoFocus,
2122
setIsSearchOpen,
23+
expandOnFocus,
2224
}: SearchWidgetProps) => {
2325
const classes = styles();
2426
const widgetRef = useRef<HTMLDivElement>(null);
@@ -75,7 +77,7 @@ export const SearchWidget = ({
7577
ref={widgetRef}
7678
className="items-center gap-0 laptop:gap-4 justify-center flex-1"
7779
>
78-
<SearchForm className={classes.searchSize()} autoFocus={autoFocus} />
80+
<SearchForm className={classes.searchSize()} autoFocus={autoFocus} expandOnFocus={expandOnFocus} />
7981
</HStack>
8082
</SearchContext.Provider>
8183
);

0 commit comments

Comments
 (0)