Skip to content

Commit

Permalink
Update built-in components
Browse files Browse the repository at this point in the history
  • Loading branch information
danez committed Nov 16, 2024
1 parent 26f1e0e commit 0729537
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 155 deletions.
5 changes: 2 additions & 3 deletions packages/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@
"@codemirror/lang-javascript": "6.2.2",
"@codemirror/lang-json": "6.0.1",
"@codemirror/view": "6.34.1",
"@headlessui/react": "1.7.19",
"@popperjs/core": "2.11.8",
"@headlessui/react": "2.2.0",
"@types/react": "18.3.11",
"@types/react-dom": "18.3.1",
"@uiw/react-codemirror": "4.23.5",
"clsx": "2.1.1",
"next": "14.2.16",
"next-themes": "0.3.0",
"next-themes": "0.4.3",
"nextra": "3.2.3",
"nextra-theme-docs": "3.2.3",
"postcss": "8.4.47",
Expand Down
131 changes: 55 additions & 76 deletions packages/website/src/components/Select.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { ReactElement, ReactNode } from 'react';
import {
Listbox,
ListboxButton,
ListboxOption,
ListboxOptions,
} from '@headlessui/react';
import cn from 'clsx';
import { Listbox, Transition } from '@headlessui/react';
import { CheckIcon } from 'nextra/icons';
import { usePopper } from '../utils/usePopper';
import { createPortal } from 'react-dom';
import { useMounted } from 'nextra/hooks';
import type { ReactElement } from 'react';

interface MenuOption {
key: string;
Expand All @@ -26,82 +28,59 @@ export function Select({
title,
className,
}: MenuProps): ReactElement {
const [trigger, container] = usePopper({
strategy: 'fixed',
placement: 'top-start',
modifiers: [
{ name: 'offset', options: { offset: [0, 10] } },
{
name: 'sameWidth',
enabled: true,
fn({ state }) {
state.styles.popper.minWidth = `${state.rects.reference.width}px`;
},
phase: 'beforeWrite',
requires: ['computeStyles'],
},
],
});

return (
<Listbox value={selected} onChange={onChange}>
{({ open }) => (
<Listbox.Button
ref={trigger}
title={title}
className={cn(
'h-7 rounded-md px-2 text-left text-xs font-medium text-gray-600 transition-colors dark:text-gray-400',
<ListboxButton
title={title}
className={({ hover, open, focus }) =>
cn(
'h-7 rounded-md px-2 text-xs font-medium transition-colors',
open
? 'dark:bg-primary-100/10 bg-gray-200 text-gray-900 dark:text-gray-50'
: 'dark:hover:bg-primary-100/5 hover:bg-gray-100 hover:text-gray-900 dark:hover:text-gray-50',
: hover
? 'dark:bg-primary-100/5 bg-gray-100 text-gray-900 dark:text-gray-50'
: 'text-gray-600 dark:text-gray-400',
focus && 'nextra-focusable',
className,
)}
>
{selected.name}
<Portal>
<Transition
ref={container}
show={open}
as={Listbox.Options}
className="z-20 max-h-64 overflow-auto rounded-md bg-white py-1 text-sm shadow-lg ring-1 ring-black/5 dark:bg-neutral-800 dark:ring-white/20"
leave="transition-opacity"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
{options.map((option) => (
<Listbox.Option
key={option.key}
value={option}
className={({ active }) =>
cn(
active
? 'bg-primary-50 text-primary-600 dark:bg-primary-500/10'
: 'text-gray-800 dark:text-gray-100',
'relative cursor-pointer whitespace-nowrap py-1.5',
'transition-colors ltr:pl-3 ltr:pr-9 rtl:pl-9 rtl:pr-3',
)
}
>
{option.name}
{option.key === selected.key && (
<span className="absolute inset-y-0 flex items-center ltr:right-3 rtl:left-3">
<CheckIcon />
</span>
)}
</Listbox.Option>
))}
</Transition>
</Portal>
</Listbox.Button>
)}
)
}
>
{selected.name}
</ListboxButton>
<ListboxOptions
as="ul"
transition
anchor={{ to: 'top start', gap: 10 }}
className={({ open }) =>
cn(
'nextra-focus',
open ? 'opacity-100' : 'opacity-0',
'z-20 max-h-64 min-w-[--button-width] rounded-md border border-black/5 bg-[rgb(var(--nextra-bg),.8)] py-1 text-sm shadow-lg backdrop-blur-lg transition-opacity motion-reduce:transition-none dark:border-white/20',
)
}
>
{options.map((option) => (
<ListboxOption
key={option.key}
value={option}
as="li"
className={({ focus }) =>
cn(
focus
? 'bg-primary-50 text-primary-600 dark:bg-primary-500/10'
: 'text-gray-800 dark:text-gray-100',
'cursor-pointer whitespace-nowrap px-3 py-1.5',
'transition-colors',
option.key === selected.key &&
'flex items-center justify-between gap-3',
)
}
>
{option.name}
{option.key === selected.key && <CheckIcon height="16" />}
</ListboxOption>
))}
</ListboxOptions>
</Listbox>
);
}

function Portal(props: { children: ReactNode }): ReactElement | null {
const mounted = useMounted();

if (!mounted) return null;

return createPortal(props.children, document.body);
}
42 changes: 0 additions & 42 deletions packages/website/src/utils/usePopper.ts

This file was deleted.

38 changes: 4 additions & 34 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0729537

Please sign in to comment.