Improve filters UI

This commit is contained in:
MartinBraquet
2026-02-09 13:57:31 +01:00
parent fba4436a08
commit 079ec8fc7e
12 changed files with 54 additions and 40 deletions

View File

@@ -1,7 +1,7 @@
import { DotsHorizontalIcon } from '@heroicons/react/solid'
import { Fragment, ReactNode, useState } from 'react'
import { usePopper } from 'react-popper'
import { Popover, Transition } from '@headlessui/react'
import {DotsHorizontalIcon} from '@heroicons/react/solid'
import {Fragment, ReactNode, useState} from 'react'
import {usePopper} from 'react-popper'
import {Popover, Transition} from '@headlessui/react'
import clsx from 'clsx'
export type DropdownItem = {
@@ -51,7 +51,7 @@ export default function DropdownMenu(props: {
<Popover.Button
ref={setReferenceElement}
className={clsx(
'text-ink-500 hover:text-ink-800 flex items-center',
'text-ink-500 hover-bold flex items-center',
buttonClass
)}
onClick={(e: any) => {

View File

@@ -561,7 +561,7 @@ export function DesktopFilters(props: {
/>
}
popoverClassName="bg-canvas-50"
menuWidth="w-50 max-h-[400px] overflow-y-auto"
menuWidth="w-100 max-h-[400px] overflow-y-auto"
/>
{/* POLITICS */}
@@ -643,7 +643,7 @@ export function DesktopFilters(props: {
<MbtiFilter filters={filters} updateFilter={updateFilter} />
}
popoverClassName="bg-canvas-50"
menuWidth="w-[350px] grid-cols-2"
menuWidth="w-[400px]"
/>
{/* EDUCATION */}

View File

@@ -66,6 +66,7 @@ export function InterestFilter(props: {
selected={filters[label] ?? []}
choices={sortedChoices as any}
onChange={(c) => updateFilter({[label]: c})}
optionsClassName={'w-[200px] sm:w-[400px]'}
/>
)
}

View File

@@ -66,6 +66,7 @@ export function LanguageFilter(props: {
onChange={(c) => {
updateFilter({languages: c})
}}
optionsClassName={'w-[200px] sm:w-[400px]'}
/>
)
}

View File

@@ -57,7 +57,7 @@ export function MbtiFilter(props: {
return (
<MultiCheckbox
className={'grid grid-cols-2 xs:grid-cols-4'}
optionsClassName={'grid grid-cols-2 xs:grid-cols-4'}
selected={filters.mbti ?? []}
choices={MBTI_CHOICES as any}
translationPrefix={'profile.mbti'}

View File

@@ -18,11 +18,11 @@ export function MyMatchesToggle(props: {
const label = t('filter.mine_toggle', 'Your filters')
return (
<Row className={clsx('mr-2 items-center', on && 'font-semibold')}>
<Row className={clsx('mr-2 items-center hover-bold', on && 'font-semibold')}>
<input
id={label}
type="checkbox"
className="border-ink-300 bg-canvas-0 dark:border-ink-500 text-primary-600 focus:ring-primary-500 h-4 w-4 rounded"
className="border-ink-300 bg-canvas-0 dark:border-ink-500 text-primary-600 focus:ring-primary-500 h-4 w-4 rounded hover:bg-canvas-200"
checked={on}
onChange={(e) => setYourFilters(e.target.checked)}
/>

View File

@@ -70,7 +70,7 @@ export function ReligionFilter(props: {
onChange={(c) => {
updateFilter({religion: c})
}}
className={className}
optionsClassName={className}
/>
</>
)

View File

@@ -19,11 +19,11 @@ export function ShortBioToggle(props: {
const on = filters.shortBio || false
return (
<Row className={clsx('mr-2 items-center', on && 'font-semibold')}>
<Row className={clsx('mr-2 items-center hover-bold', on && 'font-semibold')}>
<input
id={label}
type="checkbox"
className="border-ink-300 bg-canvas-0 dark:border-ink-500 text-primary-600 focus:ring-primary-500 h-4 w-4 rounded"
className="border-ink-300 bg-canvas-0 dark:border-ink-500 text-primary-600 focus:ring-primary-500 h-4 w-4 rounded hover:bg-canvas-200"
checked={on}
onChange={(e) => updateFilter({shortBio: e.target.checked ? true : undefined})}
/>

View File

@@ -14,6 +14,7 @@ export const MultiCheckbox = (props: {
selected: string[]
onChange: (selected: string[]) => void
className?: string
optionsClassName?: string
// If provided, enables adding a new option and should persist it (e.g. to DB)
// Return value can be:
// - string: the stored value for the new option; label will be the input text
@@ -23,7 +24,7 @@ export const MultiCheckbox = (props: {
addPlaceholder?: string
translationPrefix?: string
}) => {
const {choices, selected, onChange, className, addOption, addPlaceholder, translationPrefix} = props
const {choices, selected, onChange, className, optionsClassName, addOption, addPlaceholder, translationPrefix} = props
// Keep a local merged copy to allow optimistic adds while remaining in sync with props
const [localChoices, setLocalChoices] = useState<{ [key: string]: string }>(choices)
@@ -125,7 +126,7 @@ export const MultiCheckbox = (props: {
</Row>
)}
<Row className={clsx('flex-wrap')}>
<Row className={clsx('flex-wrap', optionsClassName)}>
{filteredEntries.map(([key, value]) => (
<Checkbox
key={key}

View File

@@ -10,30 +10,26 @@ export function Checkbox(props: {
const { label, checked, toggle, className, disabled } = props
return (
<div className={clsx(className, 'space-y-5 px-2 py-1 hover:bg-canvas-200 hover:rounded')}>
<div className="relative flex items-center">
<div className="flex h-6 items-center">
<input
id={label}
type="checkbox"
className="border-ink-300 bg-canvas-0 dark:border-ink-500 text-primary-600 focus:ring-primary-500 h-5 w-5 rounded"
checked={checked}
onChange={(e) => toggle(e.target.checked)}
disabled={disabled}
/>
</div>
<div className="ml-3">
<label
htmlFor={label}
className={clsx(
'whitespace-nowrap font-medium',
disabled ? 'text-ink-300' : 'text-ink-700'
)}
>
{label}
</label>
</div>
</div>
<div className={clsx(className, 'space-y-5 px-2 py-1')}>
<label
className={clsx('relative flex items-center cursor-pointer select-none hover-bold', disabled && 'cursor-not-allowed')}>
<input
id={label}
type="checkbox"
className="border-ink-300 bg-canvas-0 dark:border-ink-500 text-primary-600 focus:ring-primary-500 h-5 w-5 rounded hover:bg-canvas-300"
checked={checked}
onChange={(e) => toggle(e.target.checked)}
disabled={disabled}
/>
<span
className={clsx(
'ml-3 whitespace-nowrap font-medium',
disabled ? 'text-ink-300' : 'text-ink-700'
)}
>
{label}
</span>
</label>
</div>
)
}

View File

@@ -46,7 +46,7 @@ export function CustomizeableDropdown(props: {
<>
<Popover.Button
ref={setReferenceElement}
className={clsx('flex items-center relative', buttonClass)}
className={clsx('flex items-center relative hover-bold', buttonClass)}
onClick={(e: any) => {
e.stopPropagation()
}}

View File

@@ -533,3 +533,18 @@ ol > li::marker {
opacity: 0.55;
font-size: 14px;
}
input {
transition: background-color 0.2s ease-in-out;
}
.hover-bold {
transition: text-shadow 0.2s ease;
}
.hover-bold:hover {
text-shadow: 0.01em 0 currentColor,
-0.01em 0 currentColor,
0 0.01em currentColor,
0 -0.01em currentColor;
}