Skip to content

Commit 7e4f5c0

Browse files
committed
refactor(tailwind): refactor autocomplete component
1 parent 91d1fb6 commit 7e4f5c0

15 files changed

Lines changed: 129 additions & 85 deletions

File tree

apps/showcase/demo/tailwind/autocomplete/chip-demo.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@
22
import {
33
AutoComplete,
44
AutoCompleteEmpty,
5-
AutoCompleteInput,
65
AutoCompleteList,
76
AutoCompletePopup,
87
AutoCompletePortal,
9-
AutoCompletePositioner,
10-
AutoCompleteTrigger
8+
AutoCompletePositioner
119
} from '@/components/ui/autocomplete';
1210
import { Chip, ChipLabel, ChipRemove } from '@/components/ui/chip';
1311
import { Times } from '@primeicons/react';
1412
import {
13+
AutoComplete as PRAutoComplete,
1514
AutoCompleteValue,
1615
type AutoCompleteCompleteEvent,
1716
type AutoCompleteInputValueChangeEvent,
@@ -114,11 +113,11 @@ export default function ChipDemo() {
114113
inputValue={inputValue}
115114
onValueChange={onValueChange}
116115
onInputValueChange={onInputValueChange}
117-
className="w-full p-inputtext focus-within:border-primary"
116+
className="w-full rounded-md border border-surface-300 dark:border-surface-700 bg-surface-0 dark:bg-surface-950 shadow-[0_1px_2px_0_rgba(18,18,23,0.05)] focus-within:border-primary! transition-colors duration-200 p-1"
118117
>
119-
<AutoCompleteTrigger as="div" className="flex-wrap gap-1">
118+
<PRAutoComplete.Trigger as="div" className="flex flex-wrap gap-1 items-center">
120119
<AutoCompleteValue placeholder="Add a tag...">
121-
<div className="flex flex-wrap gap-1">
120+
<div className="flex flex-wrap gap-1 items-center">
122121
{selectedTags?.map((tag) => (
123122
<Chip key={tag} className="py-0.5" onRemove={(e: ChipRootRemoveEvent) => removeTag(e, tag)}>
124123
<ChipLabel className="text-xs">{tag}</ChipLabel>
@@ -128,10 +127,14 @@ export default function ChipDemo() {
128127
</Chip>
129128
))}
130129

131-
<AutoCompleteInput placeholder="Search..." className="text-sm px-2 py-0.5 outline-none" onKeyDown={onInputKeyDown} />
130+
<PRAutoComplete.Input
131+
placeholder="Search..."
132+
className="text-sm px-2 py-0.5 outline-none border-none bg-transparent flex-1 min-w-20 text-surface-700 dark:text-surface-0 placeholder:text-surface-500 dark:placeholder:text-surface-400"
133+
onKeyDown={onInputKeyDown}
134+
/>
132135
</div>
133136
</AutoCompleteValue>
134-
</AutoCompleteTrigger>
137+
</PRAutoComplete.Trigger>
135138

136139
<AutoCompletePortal>
137140
<AutoCompletePositioner>

apps/showcase/demo/tailwind/autocomplete/clear-icon-demo.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
'use client';
2-
import { Times } from '@primeicons/react';
32
import {
43
AutoComplete,
54
AutoCompleteClear,
@@ -11,9 +10,10 @@ import {
1110
AutoCompletePortal,
1211
AutoCompletePositioner
1312
} from '@/components/ui/autocomplete';
14-
import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete';
1513
import { IconField, IconFieldInset } from '@/components/ui/iconfield';
1614
import { Tag } from '@/components/ui/tag';
15+
import { Times } from '@primeicons/react';
16+
import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete';
1717
import * as React from 'react';
1818

1919
const productCategories = [

apps/showcase/demo/tailwind/autocomplete/custom-group-demo.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
AutoCompletePositioner
1111
} from '@/components/ui/autocomplete';
1212
import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete';
13-
import type { ListboxListInstance } from '@/components/ui/listbox';
13+
import type { ListboxListInstance } from 'primereact/listbox';
1414
import * as React from 'react';
1515

1616
interface City {

apps/showcase/demo/tailwind/autocomplete/filled-demo.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export default function FilledDemo() {
1919

2020
return (
2121
<div className="flex justify-center">
22-
<AutoComplete options={items} onComplete={search} variant="filled" className="w-full md:w-56">
23-
<AutoCompleteInput className="w-full" />
22+
<AutoComplete options={items} onComplete={search} className="w-full md:w-56">
23+
<AutoCompleteInput className="w-full" variant="filled" />
2424

2525
<AutoCompletePortal>
2626
<AutoCompletePositioner>

apps/showcase/demo/tailwind/autocomplete/focus-behavior-demo.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import {
88
AutoCompletePortal,
99
AutoCompletePositioner
1010
} from '@/components/ui/autocomplete';
11-
import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete';
1211
import { Button } from '@/components/ui/button';
12+
import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete';
1313
import * as React from 'react';
1414

1515
export default function FocusBehaviorDemo() {
@@ -25,13 +25,13 @@ export default function FocusBehaviorDemo() {
2525
return (
2626
<div className="space-y-4">
2727
<div className="flex flex-wrap gap-2 justify-center">
28-
<Button size="small" severity={autoOptionFocus ? 'primary' : 'secondary'} onClick={() => setAutoOptionFocus((prev) => !prev)}>
28+
<Button size="small" severity={autoOptionFocus ? undefined : 'secondary'} onClick={() => setAutoOptionFocus((prev) => !prev)}>
2929
autoOptionFocus: {String(autoOptionFocus)}
3030
</Button>
31-
<Button size="small" severity={selectOnFocus ? 'primary' : 'secondary'} onClick={() => setSelectOnFocus((prev) => !prev)}>
31+
<Button size="small" severity={selectOnFocus ? undefined : 'secondary'} onClick={() => setSelectOnFocus((prev) => !prev)}>
3232
selectOnFocus: {String(selectOnFocus)}
3333
</Button>
34-
<Button size="small" severity={focusOnHover ? 'primary' : 'secondary'} onClick={() => setFocusOnHover((prev) => !prev)}>
34+
<Button size="small" severity={focusOnHover ? undefined : 'secondary'} onClick={() => setFocusOnHover((prev) => !prev)}>
3535
focusOnHover: {String(focusOnHover)}
3636
</Button>
3737
</div>

apps/showcase/demo/tailwind/autocomplete/invalid-demo.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ export default function InvalidDemo() {
2525
options={items}
2626
onComplete={search}
2727
onValueChange={(e: AutoCompleteValueChangeEvent) => setValue(e.value as string)}
28-
invalid={!value}
2928
className="w-full md:w-56"
29+
invalid={!value}
3030
>
3131
<AutoCompleteInput placeholder="Search" className="w-full" />
3232

@@ -43,11 +43,10 @@ export default function InvalidDemo() {
4343
options={items}
4444
onComplete={search}
4545
onValueChange={(e: AutoCompleteValueChangeEvent) => setValue2(e.value as string)}
46-
invalid={!value2}
47-
variant="filled"
4846
className="w-full md:w-56"
47+
invalid={!value2}
4948
>
50-
<AutoCompleteInput placeholder="Search" className="w-full" />
49+
<AutoCompleteInput variant="filled" placeholder="Search" className="w-full" />
5150

5251
<AutoCompletePortal>
5352
<AutoCompletePositioner>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
'use client';
2+
import { AutoComplete, AutoCompleteEmpty, AutoCompleteInput, AutoCompleteList, AutoCompleteOption, AutoCompletePopup, AutoCompletePortal, AutoCompletePositioner } from '@/components/ui/autocomplete';
3+
import { Label } from '@/components/ui/label';
4+
import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete';
5+
import * as React from 'react';
6+
7+
export default function Preview() {
8+
const [filtered, setFiltered] = React.useState<string[]>([]);
9+
10+
const search = (event: AutoCompleteCompleteEvent) => {
11+
const query = event.query.toLowerCase();
12+
13+
setFiltered(query ? options.filter((item) => item.toLowerCase().includes(query)) : [...options]);
14+
};
15+
16+
return (
17+
<div className="flex justify-center">
18+
<div className="flex flex-col">
19+
<Label>Search tutorials</Label>
20+
<AutoComplete options={filtered} onComplete={search} className="w-full md:w-72 mt-2">
21+
<AutoCompleteInput placeholder="Search..." className="w-full" />
22+
<AutoCompletePortal>
23+
<AutoCompletePositioner>
24+
<AutoCompletePopup>
25+
<AutoCompleteList>
26+
{filtered.map((item, index) => (
27+
<AutoCompleteOption key={item} index={index} uKey={item}>
28+
{item}
29+
</AutoCompleteOption>
30+
))}
31+
<AutoCompleteEmpty className="text-sm">No results found</AutoCompleteEmpty>
32+
</AutoCompleteList>
33+
</AutoCompletePopup>
34+
</AutoCompletePositioner>
35+
</AutoCompletePortal>
36+
</AutoComplete>
37+
<small className="text-surface-500 mt-1.5 opacity-75">
38+
Type <em className="underline">react</em> to see suggestions
39+
</small>
40+
</div>
41+
</div>
42+
);
43+
}
44+
45+
const options: string[] = [
46+
'responsive design fundamentals',
47+
'redux toolkit crash course',
48+
'real-time chat app tutorial',
49+
'reading json files in node',
50+
'react hooks tutorial',
51+
'react server components explained',
52+
'react vs vue 2024',
53+
'react native crash course',
54+
'react 19 new features',
55+
'react context api best practices',
56+
'react testing library guide',
57+
'react router v7 tutorial',
58+
'react performance optimization',
59+
'react suspense and lazy loading',
60+
'react state management comparison',
61+
'react form validation',
62+
'react design patterns',
63+
'react authentication tutorial',
64+
'react with typescript beginner',
65+
'react animation libraries',
66+
'react deploy to production'
67+
];

apps/showcase/demo/tailwind/autocomplete/trigger-demo.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
'use client';
2-
import { ChevronDown } from '@primeicons/react';
32
import {
43
AutoComplete,
54
AutoCompleteInput,
@@ -9,8 +8,8 @@ import {
98
AutoCompletePositioner,
109
AutoCompleteTrigger
1110
} from '@/components/ui/autocomplete';
12-
import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete';
1311
import { InputGroup, InputGroupAddon } from '@/components/ui/inputgroup';
12+
import type { AutoCompleteCompleteEvent } from 'primereact/autocomplete';
1413
import * as React from 'react';
1514

1615
export default function TriggerDemo() {
@@ -25,10 +24,8 @@ export default function TriggerDemo() {
2524
<AutoComplete options={items} onComplete={search}>
2625
<InputGroup>
2726
<AutoCompleteInput />
28-
<InputGroupAddon className="p-0">
29-
<AutoCompleteTrigger className="w-full h-full flex items-center justify-center">
30-
<ChevronDown />
31-
</AutoCompleteTrigger>
27+
<InputGroupAddon>
28+
<AutoCompleteTrigger />
3229
</InputGroupAddon>
3330
</InputGroup>
3431

apps/showcase/docs/tailwind/components/autocomplete/features.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: AutoComplete is an input component that provides real-time suggesti
44
component: autocomplete
55
---
66

7-
<DocDemoViewer name="autocomplete:basic-demo" mode="collapsible" hideName />
7+
<DocDemoViewer name="autocomplete:preview" mode="collapsible" />
88

99
## Usage
1010

packages/@primereact/headless/src/autocomplete/useAutoComplete.props.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const defaultProps: useAutoCompleteProps = {
1515
optionGroupLabel: undefined,
1616
optionGroupChildren: undefined,
1717
disabled: false,
18+
invalid: false,
1819
locale: undefined,
1920
metaKeySelection: false,
2021
multiple: false,

0 commit comments

Comments
 (0)