Skip to content

fix #259 partially converting some of the components from headlessui to shadcn #531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 53 additions & 60 deletions app/(static)/deck/components/DropdownProto.tsx
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a select component from shadcn not a popover.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay will make the changes

Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Menu, Transition } from "@headlessui/react";
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
import { Fragment, Dispatch, SetStateAction } from "react";

function classNames(...classes: string[]) {
return classes.filter(Boolean).join(" ");
}
import { CheckIcon} from "lucide-react";
import { Dispatch, SetStateAction, useState } from "react";
import * as React from "react"
import {
Select,
SelectContent,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { cn } from "@/lib/utils";

interface DropDownProps {
options: string[];
Expand All @@ -17,58 +20,48 @@ export default function DropDown({
option,
setOption,
}: DropDownProps) {
return (
<Menu as="div" className="relative block text-left w-full">
<div>
<Menu.Button className="inline-flex w-full justify-between items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-gray-400 font-light shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue">
{option}
<ChevronDownIcon
className="-mr-1 ml-2 h-5 w-5 ui-open:hidden"
aria-hidden="true"
/>
<ChevronUpIcon
className="-mr-1 ml-2 h-5 w-5 hidden ui-open:block"
aria-hidden="true"
/>
</Menu.Button>
</div>
const [menuOpen, setMenuOpen] = useState<boolean>(false);
const [isFirstClick, setIsFirstClick] = useState<boolean>(false);

<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items
className="absolute left-0 z-10 mt-2 w-full origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
key={option}
>
<div className="">
{options.map((optionItem) => (
<Menu.Item key={optionItem}>
{({ active }) => (
<button
onClick={() => setOption(optionItem)}
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-gray-700",
option === optionItem ? "bg-gray-200" : "",
"px-4 py-2 text-sm w-full text-left flex items-center space-x-2 justify-between",
)}
>
<span>{optionItem}</span>
{option === optionItem ? (
<CheckIcon className="w-4 h-4 text-bold" />
) : null}
</button>
)}
</Menu.Item>
))}
</div>
</Menu.Items>
</Transition>
</Menu>
);
const handleMenuStateChange = (open: boolean) => {
if (isFirstClick) {
setMenuOpen(true); // Keep the dropdown open on the first click
return;
}

// If the menu is closed, reset the isFirstClick state
if (!open) {
setIsFirstClick(false);
setMenuOpen(false); // Ensure the dropdown is closed
} else {
setMenuOpen(true); // Open the dropdown
}
};
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed. This is only to for a double-click delete confirmation

return (
<Select open={menuOpen} onOpenChange={handleMenuStateChange}>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<Select open={menuOpen} onOpenChange={handleMenuStateChange}>
<Select>

<SelectTrigger className="inline-flex w-full justify-between items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-gray-400 font-light shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue text-base">
<SelectValue placeholder={option}/>
</SelectTrigger>
<SelectContent>
{options.map((optionItem) => (
<button
onClick={() => {
setOption(optionItem)
setMenuOpen(false)
}}
className={cn(
option === optionItem ? "bg-gray-200" : "hover:bg-gray-100",
"px-4 py-2 text-sm w-full text-left flex items-center space-x-2 justify-between",
)}
>
<span>{optionItem}</span>
{option === optionItem ? (
<CheckIcon className="w-4 h-4 text-bold" />
) : null}
</button>
))}
</SelectContent>
</Select>
)
}

22 changes: 1 addition & 21 deletions app/(static)/investors/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,9 @@
import Head from "next/head";
import Link from "next/link";
import { notFound } from "next/navigation";

import { Disclosure } from "@headlessui/react";
import { CheckIcon } from "lucide-react";
import { XIcon } from "lucide-react";
import {
RefreshCw as ArrowPathIcon,
GitPullRequestArrow as CloudArrowUpIcon,
Settings as Cog6ToothIcon,
Fingerprint as FingerPrintIcon,
Lock as LockClosedIcon,
Minus as MinusSmallIcon,
Plus as PlusSmallIcon,
HardDrive as ServerIcon,
} from "lucide-react";

import { Button } from "@/components/ui/button";
import Footer from "@/components/web/footer";
import { LogoCloud } from "@/components/web/landing-page/logo-cloud";
import Navbar from "@/components/web/navbar";

import { getInvestor } from "@/lib/content/investor";
import { cn } from "@/lib/utils";
import { classNames } from "@/lib/utils";

export default async function InvestorPage({
params,
Expand Down Expand Up @@ -274,7 +254,7 @@ export default async function InvestorPage({
x={86}
/>
</svg>
<blockquote className="text-balance text-xl font-medium leading-8 text-black text-gray-800 sm:text-2xl sm:leading-9">
<blockquote className="text-balance text-xl font-medium leading-8 text-gray-800 sm:text-2xl sm:leading-9">
<p>
Papermark solved a big pain point for me. DocSend
monopoly will end soon!
Expand Down
7 changes: 4 additions & 3 deletions components/ui/accordion.tsx
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to change the accordion behaviour. Let's leave the chevron. This component is used in other places and relies on the chevron.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from "react";

import * as AccordionPrimitive from "@radix-ui/react-accordion";
import { ChevronDown } from "lucide-react";
import { Minus as MinusSmallIcon ,Plus as PlusSmallIcon } from "lucide-react";

import { cn } from "@/lib/utils";

Expand All @@ -27,13 +27,14 @@ const AccordionTrigger = React.forwardRef<
<AccordionPrimitive.Trigger
ref={ref}
className={cn(
"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline group",
className,
)}
{...props}
>
{children}
<ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
<PlusSmallIcon className="h-6 w-6 shrink-0 transition-transform duration-200 group-data-[state=open]:hidden" />
<MinusSmallIcon className="h-6 w-6 shrink-0 transition-transform duration-200 group-data-[state=closed]:hidden" />
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>
));
Expand Down
114 changes: 53 additions & 61 deletions components/web/alternatives/dropdownproto.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Dispatch, Fragment, SetStateAction } from "react";

import { Menu, Transition } from "@headlessui/react";
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";

function classNames(...classes: string[]) {
return classes.filter(Boolean).join(" ");
}
import { CheckIcon} from "lucide-react";
import { Dispatch, SetStateAction, useState } from "react";
import * as React from "react"
import {
Select,
SelectContent,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { cn } from "@/lib/utils";

interface DropDownProps {
options: string[];
Expand All @@ -18,58 +20,48 @@ export default function DropDown({
option,
setOption,
}: DropDownProps) {
return (
<Menu as="div" className="relative block w-full text-left">
<div>
<Menu.Button className="inline-flex w-full items-center justify-between rounded-md border border-black bg-white px-4 py-2 text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none">
{option}
<ChevronDownIcon
className="-mr-1 ml-2 h-5 w-5 ui-open:hidden"
aria-hidden="true"
/>
<ChevronUpIcon
className="-mr-1 ml-2 hidden h-5 w-5 ui-open:block"
aria-hidden="true"
/>
</Menu.Button>
</div>
const [menuOpen, setMenuOpen] = useState<boolean>(false);
const [isFirstClick, setIsFirstClick] = useState<boolean>(false);

<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items
className="absolute left-0 z-10 mt-2 w-full origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
key={option}
>
<div className="">
{options.map((optionItem) => (
<Menu.Item key={optionItem}>
{({ active }) => (
<button
onClick={() => setOption(optionItem)}
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-gray-700",
option === optionItem ? "bg-gray-200" : "",
"flex w-full items-center justify-between space-x-2 px-4 py-2 text-left text-sm",
)}
>
<span>{optionItem}</span>
{option === optionItem ? (
<CheckIcon className="text-bold h-4 w-4" />
) : null}
</button>
)}
</Menu.Item>
))}
</div>
</Menu.Items>
</Transition>
</Menu>
);
const handleMenuStateChange = (open: boolean) => {
if (isFirstClick) {
setMenuOpen(true); // Keep the dropdown open on the first click
return;
}

// If the menu is closed, reset the isFirstClick state
if (!open) {
setIsFirstClick(false);
setMenuOpen(false); // Ensure the dropdown is closed
} else {
setMenuOpen(true); // Open the dropdown
}
};
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No needed. same as above

return (
<Select open={menuOpen} onOpenChange={handleMenuStateChange}>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<Select open={menuOpen} onOpenChange={handleMenuStateChange}>
<Select>

<SelectTrigger className="inline-flex w-full justify-between items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-gray-400 font-light shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue text-base">
<SelectValue placeholder={option}/>
</SelectTrigger>
<SelectContent>
{options.map((optionItem) => (
<button
onClick={() => {
setOption(optionItem)
setMenuOpen(false)
}}
className={cn(
option === optionItem ? "bg-gray-200" : "hover:bg-gray-100",
"px-4 py-2 text-sm w-full text-left flex items-center space-x-2 justify-between",
)}
>
<span>{optionItem}</span>
{option === optionItem ? (
<CheckIcon className="w-4 h-4 text-bold" />
) : null}
</button>
))}
</SelectContent>
</Select>
)
}

54 changes: 19 additions & 35 deletions components/web/faq.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
"use client";

import { Disclosure } from "@headlessui/react";
import { Minus as MinusSmallIcon, Plus as PlusSmallIcon } from "lucide-react";

import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
const faqs = [
{
question: "What is Papermark?",
Expand Down Expand Up @@ -44,38 +46,20 @@ const faqs = [
export default function Faq() {
return (
<div className="">
<dl className="mt-10 space-y-6 divide-y divide-gray-800/10 ">
{faqs.map((faq) => (
<Disclosure as="div" key={faq.question} className="pt-6">
{({ open }) => (
<>
<dt>
<Disclosure.Button className="flex w-full items-start justify-between text-left text-gray-800">
<span className="text-balance font-medium leading-7">
{faq.question}
</span>
<span className="ml-6 flex h-7 items-center">
{open ? (
<MinusSmallIcon
className="h-6 w-6"
aria-hidden="true"
/>
) : (
<PlusSmallIcon className="h-6 w-6" aria-hidden="true" />
)}
</span>
</Disclosure.Button>
</dt>
<Disclosure.Panel as="dd" className="mt-2 pr-12">
<p className="text-balance leading-7 text-gray-500">
<dl className="mt-10 divide-y divide-gray-800/10">
{faqs.map((faq) => (
<Accordion key={faq.question} type="single" collapsible>
<AccordionItem value={faq.question} className="py-2 border-none">
<AccordionTrigger className="text-left text-gray-800 dark:text-gray-200 text-balance font-medium leading-7 hover:no-underline">
{faq.question}
</AccordionTrigger>
<AccordionContent className="text-base leading-7 text-gray-500">
{faq.answer}
</p>
</Disclosure.Panel>
</>
)}
</Disclosure>
))}
</dl>
</AccordionContent>
</AccordionItem>
</Accordion>
))}
</dl>
</div>
);
}
1 change: 0 additions & 1 deletion package-lock.json

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

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"@aws-sdk/s3-request-presigner": "^3.614.0",
"@chronark/zod-bird": "^0.3.9",
"@github/webauthn-json": "^2.1.1",
"@headlessui/react": "^1.7.19",
"@jitsu/js": "^1.9.5",
"@mdx-js/loader": "^3.0.1",
"@mdx-js/react": "^3.0.1",
Expand Down
Loading