This commit is contained in:
Joshua Coles 2023-09-27 17:53:11 +01:00
parent 272bddab4f
commit b8cd715d2a
4 changed files with 122 additions and 3 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -10,8 +10,12 @@
"preview": "vite preview"
},
"dependencies": {
"@headlessui/react": "^1.7.17",
"@heroicons/react": "^2.0.18",
"@tanstack/react-query": "^4.35.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-select": "^5.7.5"
},
"devDependencies": {
"@types/react": "^18.0.37",

110
src/ComboBox.tsx Normal file
View File

@ -0,0 +1,110 @@
/*
This example requires some changes to your config:
```
// tailwind.config.js
module.exports = {
// ...
plugins: [
// ...
require('@tailwindcss/forms'),
],
}
```
*/
import {useMemo, useState} from 'react'
import {CheckIcon, ChevronUpDownIcon} from '@heroicons/react/20/solid'
import {Combobox} from '@headlessui/react'
import {useQuery} from "@tanstack/react-query";
function classNames(...classes: any[]) {
return classes.filter(Boolean).join(' ')
}
export default function Example() {
const {data: options} = useQuery({
queryKey: ['obsidian-metadata'],
initialData: [],
queryFn: async () => {
const response = await fetch("http://100.115.154.44:9002/metadata")
const fullData: any[] = await response.json();
return fullData.map(md => ({
id: md.relativePath,
name: md.fileName
}));
},
});
const [query, setQuery] = useState('')
const [selectedPerson, setSelectedPerson] = useState(null)
const filteredOptions =
useMemo(() => {
return query === ''
? options
: options.filter((option) => {
return option.name.toLowerCase().includes(query.toLowerCase())
})
}, [query, options])
return (
<Combobox as="div" value={selectedPerson} onChange={setSelectedPerson}>
<Combobox.Label className="block text-sm font-medium leading-6 text-gray-900">Assigned to</Combobox.Label>
<div className="relative mt-2">
<Combobox.Input
className="w-full rounded-md border-0 bg-white py-1.5 pl-3 pr-12 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
onChange={(event) => setQuery(event.target.value)}
displayValue={(person: (typeof filteredOptions)[number]) => person?.name}
/>
<Combobox.Button className="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none">
<ChevronUpDownIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
</Combobox.Button>
{filteredOptions.length > 0 && (
<Combobox.Options className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{filteredOptions.map((person) => (
<Combobox.Option
key={person.id}
value={person}
className={({ active }) =>
classNames(
'relative cursor-default select-none py-2 pl-3 pr-9',
active ? 'bg-indigo-600 text-white' : 'text-gray-900'
)
}
>
{({ active, selected }) => (
<>
<div className="flex">
<span className={classNames('truncate', selected && 'font-semibold')}>{person.name}</span>
<span
className={classNames(
'ml-2 truncate text-gray-500',
active ? 'text-indigo-200' : 'text-gray-500'
)}
>
{person.id}
</span>
</div>
{selected && (
<span
className={classNames(
'absolute inset-y-0 right-0 flex items-center pr-4',
active ? 'text-white' : 'text-indigo-600'
)}
>
<CheckIcon className="h-5 w-5" aria-hidden="true" />
</span>
)}
</>
)}
</Combobox.Option>
))}
</Combobox.Options>
)}
</div>
</Combobox>
)
}

View File

@ -1,10 +1,15 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import Combobox from "./ComboBox.tsx";
import {QueryClient, QueryClientProvider} from "@tanstack/react-query";
const queryClient = new QueryClient()
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<App/>
<QueryClientProvider client={queryClient}>
<Combobox/>
</QueryClientProvider>
</React.StrictMode>,
)