~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
35 lines · 1.7 KB Raw History
import { Dialog as BaseDialog } from '@base-ui/react/dialog';
import { XIcon } from 'lucide-react';
import { cn } from '#/lib/utils.js';

/** A centered modal. `trigger` (an element) opens it; `title` heads it. */
export function Dialog({ trigger, title, children, className }) {
  return (
    <BaseDialog.Root>
      <BaseDialog.Trigger render={trigger} />
      <BaseDialog.Portal>
        <BaseDialog.Backdrop className="fixed inset-0 z-40 bg-black/60 backdrop-blur-sm" />
        <BaseDialog.Popup
          className={cn(
            'fixed top-1/2 left-1/2 z-50 flex max-h-[85vh] w-[calc(100vw-2rem)] max-w-md -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-3xl border border-border bg-card p-6 shadow-2xl outline-none',
            className,
          )}
        >
          <div className="mb-4 flex items-center gap-3">
            <h3 className="font-extrabold text-[17px] text-foreground tracking-tight">
              {title}
            </h3>
            <div className="flex-1" />
            <BaseDialog.Close className="grid size-8 shrink-0 place-items-center rounded-xl text-faint outline-none transition-colors hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 [&_svg]:size-4">
              <XIcon />
            </BaseDialog.Close>
          </div>
          {/* The scroll container clips on both axes, and a control's focus
              ring is a shadow outside its box. The padding gives rings room;
              the negative margin keeps the layout where it was. */}
          <div className="-m-1 overflow-y-auto p-1">{children}</div>
        </BaseDialog.Popup>
      </BaseDialog.Portal>
    </BaseDialog.Root>
  );
}