|
1 | | -import { AdjustmentsHorizontalIcon, CheckIcon, XMarkIcon } from "@heroicons/react/20/solid"; |
| 1 | +import { |
| 2 | + AdjustmentsHorizontalIcon, |
| 3 | + CheckIcon, |
| 4 | + CubeIcon, |
| 5 | + XMarkIcon, |
| 6 | +} from "@heroicons/react/20/solid"; |
| 7 | +import * as Ariakit from "@ariakit/react"; |
2 | 8 | import { Form, type MetaFunction, useFetcher } from "@remix-run/react"; |
3 | 9 | import { type LoaderFunctionArgs } from "@remix-run/server-runtime"; |
4 | 10 | import { AnimatePresence, motion } from "framer-motion"; |
@@ -26,7 +32,6 @@ import { SearchInput } from "~/components/primitives/SearchInput"; |
26 | 32 | import { Switch } from "~/components/primitives/Switch"; |
27 | 33 | import { |
28 | 34 | SelectProvider, |
29 | | - SelectTrigger, |
30 | 35 | SelectPopover, |
31 | 36 | SelectList, |
32 | 37 | SelectItem, |
@@ -117,70 +122,60 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { |
117 | 122 | function ProviderFilter({ providers }: { providers: string[] }) { |
118 | 123 | const { values, replace, del } = useSearchParams(); |
119 | 124 | const selected = values("providers"); |
| 125 | + const hasFilter = selected.length > 0; |
120 | 126 |
|
121 | 127 | return ( |
122 | | - <> |
123 | | - <SelectProvider value={selected} setValue={(v) => replace({ providers: v })}> |
124 | | - <SelectTrigger |
125 | | - icon={<AdjustmentsHorizontalIcon className="size-4" />} |
126 | | - variant="secondary/small" |
127 | | - tooltipTitle="Filter by provider" |
128 | | - > |
129 | | - <span className="ml-0.5">Provider</span> |
130 | | - </SelectTrigger> |
131 | | - <SelectPopover> |
132 | | - <SelectList> |
133 | | - {providers.map((p) => ( |
134 | | - <SelectItem key={p} value={p}> |
135 | | - {formatProviderName(p)} |
136 | | - </SelectItem> |
137 | | - ))} |
138 | | - </SelectList> |
139 | | - </SelectPopover> |
140 | | - </SelectProvider> |
141 | | - {selected.length > 0 && ( |
| 128 | + <SelectProvider value={selected} setValue={(v) => replace({ providers: v })}> |
| 129 | + <Ariakit.Select render={<div className="group cursor-pointer focus-custom" />}> |
142 | 130 | <AppliedFilter |
143 | | - label="Provider" |
144 | | - value={appliedSummary(selected.map(formatProviderName))!} |
| 131 | + icon={<CubeIcon className="size-4" />} |
| 132 | + label={hasFilter ? "Provider" : undefined} |
| 133 | + value={hasFilter ? appliedSummary(selected.map(formatProviderName))! : "Provider"} |
| 134 | + valueClassName={hasFilter ? undefined : "text-text-bright"} |
| 135 | + removable={hasFilter} |
145 | 136 | onRemove={() => del("providers")} |
146 | 137 | /> |
147 | | - )} |
148 | | - </> |
| 138 | + </Ariakit.Select> |
| 139 | + <SelectPopover> |
| 140 | + <SelectList> |
| 141 | + {providers.map((p) => ( |
| 142 | + <SelectItem key={p} value={p}> |
| 143 | + {formatProviderName(p)} |
| 144 | + </SelectItem> |
| 145 | + ))} |
| 146 | + </SelectList> |
| 147 | + </SelectPopover> |
| 148 | + </SelectProvider> |
149 | 149 | ); |
150 | 150 | } |
151 | 151 |
|
152 | 152 | function FeaturesFilter({ features }: { features: string[] }) { |
153 | 153 | const { values, replace, del } = useSearchParams(); |
154 | 154 | const selected = values("features"); |
| 155 | + const hasFilter = selected.length > 0; |
155 | 156 |
|
156 | 157 | return ( |
157 | | - <> |
158 | | - <SelectProvider value={selected} setValue={(v) => replace({ features: v })}> |
159 | | - <SelectTrigger |
160 | | - icon={<AdjustmentsHorizontalIcon className="size-4" />} |
161 | | - variant="secondary/small" |
162 | | - tooltipTitle="Filter by feature" |
163 | | - > |
164 | | - <span className="ml-0.5">Features</span> |
165 | | - </SelectTrigger> |
166 | | - <SelectPopover> |
167 | | - <SelectList> |
168 | | - {features.map((f) => ( |
169 | | - <SelectItem key={f} value={f}> |
170 | | - {formatFeature(f)} |
171 | | - </SelectItem> |
172 | | - ))} |
173 | | - </SelectList> |
174 | | - </SelectPopover> |
175 | | - </SelectProvider> |
176 | | - {selected.length > 0 && ( |
| 158 | + <SelectProvider value={selected} setValue={(v) => replace({ features: v })}> |
| 159 | + <Ariakit.Select render={<div className="group cursor-pointer focus-custom" />}> |
177 | 160 | <AppliedFilter |
178 | | - label="Features" |
179 | | - value={appliedSummary(selected.map(formatFeature))!} |
| 161 | + icon={<AdjustmentsHorizontalIcon className="size-4" />} |
| 162 | + label={hasFilter ? "Features" : undefined} |
| 163 | + value={hasFilter ? appliedSummary(selected.map(formatFeature))! : "Features"} |
| 164 | + valueClassName={hasFilter ? undefined : "text-text-bright"} |
| 165 | + removable={hasFilter} |
180 | 166 | onRemove={() => del("features")} |
181 | 167 | /> |
182 | | - )} |
183 | | - </> |
| 168 | + </Ariakit.Select> |
| 169 | + <SelectPopover> |
| 170 | + <SelectList> |
| 171 | + {features.map((f) => ( |
| 172 | + <SelectItem key={f} value={f}> |
| 173 | + {formatFeature(f)} |
| 174 | + </SelectItem> |
| 175 | + ))} |
| 176 | + </SelectList> |
| 177 | + </SelectPopover> |
| 178 | + </SelectProvider> |
184 | 179 | ); |
185 | 180 | } |
186 | 181 |
|
|
0 commit comments