<Button>
-component (#480)
-`<Button/>` component - Uses `next/link` + `<a/>` if you supply a `href` otherwise `<button/>` - Add UI sandbox - Change the `event-types/index` to use a query param for deciding if modal is open or not
This commit is contained in:
parent
ce64080160
commit
a77a15056a
7 changed files with 251 additions and 83 deletions
|
@ -1,32 +1,37 @@
|
|||
import React from "react";
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||
|
||||
export function Dialog({ children, ...props }) {
|
||||
type DialogProps = React.ComponentProps<typeof DialogPrimitive["Root"]>;
|
||||
export function Dialog(props: DialogProps) {
|
||||
const { children, ...other } = props;
|
||||
return (
|
||||
<DialogPrimitive.Root {...props}>
|
||||
<DialogPrimitive.Root {...other}>
|
||||
<DialogPrimitive.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
|
||||
{children}
|
||||
</DialogPrimitive.Root>
|
||||
);
|
||||
}
|
||||
type DialogContentProps = React.ComponentProps<typeof DialogPrimitive["Content"]>;
|
||||
|
||||
export const DialogContent = React.forwardRef(({ children, ...props }, forwardedRef) => (
|
||||
export const DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps>(
|
||||
({ children, ...props }, forwardedRef) => (
|
||||
<DialogPrimitive.Content
|
||||
{...props}
|
||||
className="fixed bg-white min-w-[360px] rounded top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-left overflow-hidden shadow-xl sm:align-middle sm:max-w-lg sm:w-full p-6"
|
||||
className="min-w-[360px] fixed left-1/2 top-1/2 p-6 text-left bg-white rounded shadow-xl overflow-hidden -translate-x-1/2 -translate-y-1/2 sm:align-middle sm:w-full sm:max-w-lg"
|
||||
ref={forwardedRef}>
|
||||
{children}
|
||||
</DialogPrimitive.Content>
|
||||
));
|
||||
)
|
||||
);
|
||||
|
||||
export function DialogHeader({ title, subtitle }: { title: string; subtitle: string }) {
|
||||
return (
|
||||
<div className="mb-8">
|
||||
<h3 className="text-lg leading-6 font-bold text-gray-900" id="modal-title">
|
||||
<h3 className="text-gray-900 text-lg font-bold leading-6" id="modal-title">
|
||||
{title}
|
||||
</h3>
|
||||
<div>
|
||||
<p className="text-sm text-gray-400">{subtitle}</p>
|
||||
<p className="text-gray-400 text-sm">{subtitle}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,10 +1,86 @@
|
|||
export default function Button(props) {
|
||||
return (
|
||||
<button type="submit" className="btn btn-primary dark:btn-white">
|
||||
{!props.loading && props.children}
|
||||
{props.loading && (
|
||||
import classNames from "@lib/classNames";
|
||||
import Link, { LinkProps } from "next/link";
|
||||
import React from "react";
|
||||
|
||||
type HTMLAnchorProps = React.AnchorHTMLAttributes<HTMLAnchorElement>;
|
||||
type HTMLButtonProps = React.ButtonHTMLAttributes<HTMLButtonProps>;
|
||||
|
||||
type SVGComponent = React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
|
||||
|
||||
export type ButtonProps = {
|
||||
color?: "primary" | "secondary" | "minimal";
|
||||
size?: "base" | "sm" | "lg";
|
||||
loading?: boolean;
|
||||
disabled?: boolean;
|
||||
onClick?: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
||||
StartIcon?: SVGComponent;
|
||||
EndIcon?: SVGComponent;
|
||||
} & ((Omit<HTMLAnchorProps, "href"> & { href: LinkProps["href"] }) | (HTMLButtonProps & { href?: never }));
|
||||
|
||||
export const Button = function Button(props: ButtonProps) {
|
||||
const {
|
||||
loading = false,
|
||||
color = "primary",
|
||||
size = "base",
|
||||
StartIcon,
|
||||
EndIcon,
|
||||
// attributes propagated from `HTMLAnchorProps` or `HTMLButtonProps`
|
||||
...passThroughProps
|
||||
} = props;
|
||||
// Buttons are **always** disabled if we're in a `loading` state
|
||||
const disabled = props.disabled || loading;
|
||||
|
||||
// If pass an `href`-attr is passed it's `<a>`, otherwise it's a `<button />`
|
||||
const isLink = typeof props.href !== "undefined";
|
||||
const elementType = isLink ? "a" : "button";
|
||||
|
||||
const element = React.createElement(
|
||||
elementType,
|
||||
{
|
||||
...passThroughProps,
|
||||
disabled,
|
||||
className: classNames(
|
||||
// base styles independent what type of button it is
|
||||
"inline-flex items-center relative",
|
||||
// different styles depending on size
|
||||
size === "sm" && "px-3 py-2 text-sm leading-4 font-medium rounded-sm",
|
||||
size === "base" && "px-3 py-2 text-sm font-medium rounded-sm",
|
||||
size === "lg" && "px-4 py-2 text-base font-medium rounded-sm",
|
||||
// different styles depending on color
|
||||
color === "primary" &&
|
||||
(disabled
|
||||
? "border border-transparent bg-gray-400 text-white"
|
||||
: "border border-transparent text-white bg-neutral-900 hover:bg-neutral-800 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-neutral-900"),
|
||||
color === "secondary" &&
|
||||
(disabled
|
||||
? "border border-gray-200 text-gray-400 bg-white"
|
||||
: "border border-gray-300 text-gray-700 bg-white hover:bg-gray-50 hover:text-gray-900 hover:shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-neutral-900"),
|
||||
color === "minimal" &&
|
||||
(disabled
|
||||
? "text-gray-400 bg-transparent"
|
||||
: "text-gray-700 bg-transparent hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-1 focus:bg-gray-100 focus:ring-neutral-500"),
|
||||
|
||||
// set not-allowed cursor if disabled
|
||||
disabled && "cursor-not-allowed",
|
||||
props.className
|
||||
),
|
||||
// if we click a disabled button, we prevent going through the click handler
|
||||
onClick: disabled
|
||||
? (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
}
|
||||
: props.onClick,
|
||||
},
|
||||
<>
|
||||
{StartIcon && <StartIcon className="inline w-5 h-5 mr-2 -ml-1" />}
|
||||
{props.children}
|
||||
{loading && (
|
||||
<div className="absolute transform -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2">
|
||||
<svg
|
||||
className="animate-spin mx-4 h-5 w-5 text-white"
|
||||
className={classNames(
|
||||
"w-5 h-5 mx-4 animate-spin",
|
||||
color === "primary" ? "text-white" : "text-black"
|
||||
)}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24">
|
||||
|
@ -20,7 +96,16 @@ export default function Button(props) {
|
|||
fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
{EndIcon && <EndIcon className="inline w-5 h-5 ml-2 -mr-1" />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
return props.href ? (
|
||||
<Link passHref href={props.href}>
|
||||
{element}
|
||||
</Link>
|
||||
) : (
|
||||
element
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export default function classNames(...classes) {
|
||||
export default function classNames(...classes: unknown[]) {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"next": "^10.2.0",
|
||||
"next": "^10.2.3",
|
||||
"next-auth": "^3.28.0",
|
||||
"next-transpile-modules": "^8.0.0",
|
||||
"nodemailer": "^6.6.3",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Dialog, DialogClose, DialogContent, DialogTrigger } from "@components/Dialog";
|
||||
import { Tooltip } from "@components/Tooltip";
|
||||
import { Dialog, DialogClose, DialogContent } from "@components/Dialog";
|
||||
import Loader from "@components/Loader";
|
||||
import { Tooltip } from "@components/Tooltip";
|
||||
import { Button } from "@components/ui/Button";
|
||||
import { Menu, Transition } from "@headlessui/react";
|
||||
import {
|
||||
ClockIcon,
|
||||
|
@ -12,6 +13,7 @@ import {
|
|||
UserIcon,
|
||||
} from "@heroicons/react/solid";
|
||||
import classNames from "@lib/classNames";
|
||||
import showToast from "@lib/notification";
|
||||
import { getSession, useSession } from "next-auth/client";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
|
@ -19,7 +21,6 @@ import { useRouter } from "next/router";
|
|||
import React, { Fragment, useRef } from "react";
|
||||
import Shell from "../../components/Shell";
|
||||
import prisma from "../../lib/prisma";
|
||||
import showToast from "@lib/notification";
|
||||
|
||||
export default function Availability({ user, types }) {
|
||||
const [session, loading] = useSession();
|
||||
|
@ -30,6 +31,8 @@ export default function Availability({ user, types }) {
|
|||
const descriptionRef = useRef<HTMLTextAreaElement>();
|
||||
const lengthRef = useRef<HTMLInputElement>();
|
||||
|
||||
const dialogOpen = router.query.new === "1";
|
||||
|
||||
async function createEventTypeHandler(event) {
|
||||
event.preventDefault();
|
||||
|
||||
|
@ -69,14 +72,23 @@ export default function Availability({ user, types }) {
|
|||
}
|
||||
|
||||
const CreateNewEventDialog = () => (
|
||||
<Dialog>
|
||||
<DialogTrigger className="py-2 px-4 mt-6 border border-transparent rounded-sm shadow-sm text-sm font-medium text-white bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
|
||||
<PlusIcon className="w-5 h-5 mr-1 inline" />
|
||||
<Dialog
|
||||
open={dialogOpen}
|
||||
onOpenChange={(isOpen) => {
|
||||
const newQuery = {
|
||||
...router.query,
|
||||
};
|
||||
delete newQuery["new"];
|
||||
if (!isOpen) {
|
||||
router.push({ pathname: router.pathname, query: newQuery });
|
||||
}
|
||||
}}>
|
||||
<Button className="mt-2" StartIcon={PlusIcon} href={{ query: { ...router.query, new: "1" } }}>
|
||||
New event type
|
||||
</DialogTrigger>
|
||||
</Button>
|
||||
<DialogContent>
|
||||
<div className="mb-8">
|
||||
<h3 className="text-lg leading-6 font-bold text-gray-900" id="modal-title">
|
||||
<h3 className="text-lg font-bold leading-6 text-gray-900" id="modal-title">
|
||||
Add a new event type
|
||||
</h3>
|
||||
<div>
|
||||
|
@ -97,7 +109,7 @@ export default function Availability({ user, types }) {
|
|||
name="title"
|
||||
id="title"
|
||||
required
|
||||
className="shadow-sm focus:ring-neutral-900 focus:border-neutral-900 block w-full sm:text-sm border-gray-300 rounded-sm"
|
||||
className="block w-full border-gray-300 rounded-sm shadow-sm focus:border-neutral-900 focus:ring-neutral-900 sm:text-sm"
|
||||
placeholder="Quick Chat"
|
||||
/>
|
||||
</div>
|
||||
|
@ -108,7 +120,7 @@ export default function Availability({ user, types }) {
|
|||
</label>
|
||||
<div className="mt-1">
|
||||
<div className="flex rounded-sm shadow-sm">
|
||||
<span className="inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500 sm:text-sm">
|
||||
<span className="inline-flex items-center px-3 text-gray-500 border border-r-0 border-gray-300 bg-gray-50 rounded-l-md sm:text-sm">
|
||||
{location.hostname}/{user.username}/
|
||||
</span>
|
||||
<input
|
||||
|
@ -117,7 +129,7 @@ export default function Availability({ user, types }) {
|
|||
name="slug"
|
||||
id="slug"
|
||||
required
|
||||
className="flex-1 block w-full focus:ring-neutral-900 focus:border-neutral-900 min-w-0 rounded-none rounded-r-md sm:text-sm border-gray-300"
|
||||
className="flex-1 block w-full min-w-0 border-gray-300 rounded-none focus:border-neutral-900 rounded-r-md focus:ring-neutral-900 sm:text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -131,7 +143,7 @@ export default function Availability({ user, types }) {
|
|||
ref={descriptionRef}
|
||||
name="description"
|
||||
id="description"
|
||||
className="shadow-sm focus:ring-neutral-900 focus:border-neutral-900 block w-full sm:text-sm border-gray-300 rounded-sm"
|
||||
className="block w-full border-gray-300 rounded-sm shadow-sm focus:border-neutral-900 focus:ring-neutral-900 sm:text-sm"
|
||||
placeholder="A quick video meeting."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -139,17 +151,17 @@ export default function Availability({ user, types }) {
|
|||
<label htmlFor="length" className="block text-sm font-medium text-gray-700">
|
||||
Length
|
||||
</label>
|
||||
<div className="mt-1 relative rounded-sm shadow-sm">
|
||||
<div className="relative mt-1 rounded-sm shadow-sm">
|
||||
<input
|
||||
ref={lengthRef}
|
||||
type="number"
|
||||
name="length"
|
||||
id="length"
|
||||
required
|
||||
className="focus:ring-neutral-900 focus:border-neutral-900 block w-full pr-20 sm:text-sm border-gray-300 rounded-sm"
|
||||
className="block w-full pr-20 border-gray-300 rounded-sm focus:border-neutral-900 focus:ring-neutral-900 sm:text-sm"
|
||||
placeholder="15"
|
||||
/>
|
||||
<div className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 text-sm">
|
||||
<div className="absolute inset-y-0 right-0 flex items-center pr-3 text-sm text-gray-400">
|
||||
minutes
|
||||
</div>
|
||||
</div>
|
||||
|
@ -159,7 +171,7 @@ export default function Availability({ user, types }) {
|
|||
<button type="submit" className="btn btn-primary">
|
||||
Continue
|
||||
</button>
|
||||
<DialogClose as="button" className="btn btn-white mx-2">
|
||||
<DialogClose as="button" className="mx-2 btn btn-white">
|
||||
Cancel
|
||||
</DialogClose>
|
||||
</div>
|
||||
|
@ -178,44 +190,44 @@ export default function Availability({ user, types }) {
|
|||
heading="Event Types"
|
||||
subtitle="Create events to share for people to book on your calendar."
|
||||
CTA={types.length !== 0 && <CreateNewEventDialog />}>
|
||||
<div className="bg-white border border-gray-200 rounded-sm overflow-hidden -mx-4 sm:mx-0">
|
||||
<div className="-mx-4 overflow-hidden bg-white border border-gray-200 rounded-sm sm:mx-0">
|
||||
<ul className="divide-y divide-neutral-200">
|
||||
{types.map((type) => (
|
||||
<li key={type.id}>
|
||||
<div className="hover:bg-neutral-50">
|
||||
<div className="px-4 py-4 flex items-center sm:px-6">
|
||||
<div className="flex items-center px-4 py-4 sm:px-6">
|
||||
<Link href={"/event-types/" + type.id}>
|
||||
<a className="min-w-0 flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<span className="truncate ">
|
||||
<a className="flex-1 min-w-0 sm:flex sm:items-center sm:justify-between">
|
||||
<span className="truncate">
|
||||
<div className="flex text-sm">
|
||||
<p className="font-medium text-neutral-900 truncate">{type.title}</p>
|
||||
<p className="font-medium truncate text-neutral-900">{type.title}</p>
|
||||
{type.hidden && (
|
||||
<span className="ml-2 inline-flex items-center px-1.5 py-0.5 rounded-sm text-xs font-medium bg-yellow-100 text-yellow-800">
|
||||
<span className="inline-flex items-center ml-2 px-1.5 py-0.5 text-yellow-800 text-xs font-medium bg-yellow-100 rounded-sm">
|
||||
Hidden
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-2 flex space-x-4">
|
||||
<div className="flex mt-2 space-x-4">
|
||||
<div className="flex items-center text-sm text-neutral-500">
|
||||
<ClockIcon
|
||||
className="flex-shrink-0 mr-1.5 h-4 w-4 text-neutral-400"
|
||||
className="flex-shrink-0 mr-1.5 w-4 h-4 text-neutral-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<p>{type.length}m</p>
|
||||
</div>
|
||||
<div className="flex items-center text-sm text-neutral-500">
|
||||
<UserIcon
|
||||
className="flex-shrink-0 mr-1.5 h-4 w-4 text-neutral-400"
|
||||
className="flex-shrink-0 mr-1.5 w-4 h-4 text-neutral-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<p>1-on-1</p>
|
||||
</div>
|
||||
<div className="flex items-center text-sm text-neutral-500">
|
||||
<InformationCircleIcon
|
||||
className="flex-shrink-0 mr-1.5 h-4 w-4 text-neutral-400"
|
||||
className="flex-shrink-0 mr-1.5 w-4 h-4 text-neutral-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div className="max-w-32 sm:max-w-full truncate">
|
||||
<div className="truncate max-w-32 sm:max-w-full">
|
||||
{type.description.substring(0, 100)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -224,15 +236,15 @@ export default function Availability({ user, types }) {
|
|||
</a>
|
||||
</Link>
|
||||
|
||||
<div className="hidden sm:flex mt-4 flex-shrink-0 sm:mt-0 sm:ml-5">
|
||||
<div className="flex overflow-hidden space-x-5">
|
||||
<div className="flex-shrink-0 hidden mt-4 sm:flex sm:ml-5 sm:mt-0">
|
||||
<div className="flex space-x-5 overflow-hidden">
|
||||
<Tooltip content="Preview">
|
||||
<a
|
||||
href={"/" + session.user.username + "/" + type.slug}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="group cursor-pointer text-neutral-400 p-2 border border-transparent hover:border-gray-200">
|
||||
<ExternalLinkIcon className="group-hover:text-black w-5 h-5" />
|
||||
className="p-2 border border-transparent cursor-pointer group text-neutral-400 hover:border-gray-200">
|
||||
<ExternalLinkIcon className="w-5 h-5 group-hover:text-black" />
|
||||
</a>
|
||||
</Tooltip>
|
||||
|
||||
|
@ -244,20 +256,20 @@ export default function Availability({ user, types }) {
|
|||
window.location.hostname + "/" + session.user.username + "/" + type.slug
|
||||
);
|
||||
}}
|
||||
className="group text-neutral-400 p-2 border border-transparent hover:border-gray-200">
|
||||
<LinkIcon className="group-hover:text-black w-5 h-5" />
|
||||
className="p-2 border border-transparent group text-neutral-400 hover:border-gray-200">
|
||||
<LinkIcon className="w-5 h-5 group-hover:text-black" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex sm:hidden ml-5 flex-shrink-0">
|
||||
<div className="flex flex-shrink-0 ml-5 sm:hidden">
|
||||
<Menu as="div" className="inline-block text-left">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<div>
|
||||
<Menu.Button className="text-neutral-400 mt-1 p-2 border border-transparent hover:border-gray-200">
|
||||
<Menu.Button className="p-2 mt-1 border border-transparent text-neutral-400 hover:border-gray-200">
|
||||
<span className="sr-only">Open options</span>
|
||||
<DotsHorizontalIcon className="h-5 w-5" aria-hidden="true" />
|
||||
<DotsHorizontalIcon className="w-5 h-5" aria-hidden="true" />
|
||||
</Menu.Button>
|
||||
</div>
|
||||
|
||||
|
@ -272,7 +284,7 @@ export default function Availability({ user, types }) {
|
|||
leaveTo="transform opacity-0 scale-95">
|
||||
<Menu.Items
|
||||
static
|
||||
className="origin-top-right absolute right-0 mt-2 w-56 rounded-sm shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none divide-y divide-neutral-100">
|
||||
className="absolute right-0 w-56 mt-2 origin-top-right bg-white divide-y rounded-sm shadow-lg focus:outline-none divide-neutral-100 ring-1 ring-black ring-opacity-5">
|
||||
<div className="py-1">
|
||||
<Menu.Item>
|
||||
{({ active }) => (
|
||||
|
@ -285,7 +297,7 @@ export default function Availability({ user, types }) {
|
|||
"group flex items-center px-4 py-2 text-sm font-medium"
|
||||
)}>
|
||||
<ExternalLinkIcon
|
||||
className="mr-3 h-4 w-4 text-neutral-400 group-hover:text-neutral-500"
|
||||
className="w-4 h-4 mr-3 text-neutral-400 group-hover:text-neutral-500"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
Preview
|
||||
|
@ -307,10 +319,10 @@ export default function Availability({ user, types }) {
|
|||
}}
|
||||
className={classNames(
|
||||
active ? "bg-neutral-100 text-neutral-900" : "text-neutral-700",
|
||||
"group flex items-center px-4 py-2 text-sm w-full font-medium"
|
||||
"group flex items-center px-4 py-2 w-full text-sm font-medium"
|
||||
)}>
|
||||
<LinkIcon
|
||||
className="mr-3 h-4 w-4 text-neutral-400 group-hover:text-neutral-500"
|
||||
className="w-4 h-4 mr-3 text-neutral-400 group-hover:text-neutral-500"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
Copy link to event
|
||||
|
@ -326,7 +338,7 @@ export default function Availability({ user, types }) {
|
|||
{/* "group flex items-center px-4 py-2 text-sm font-medium"*/}
|
||||
{/* )}>*/}
|
||||
{/* <DuplicateIcon*/}
|
||||
{/* className="mr-3 h-4 w-4 text-neutral-400 group-hover:text-neutral-500"*/}
|
||||
{/* className="w-4 h-4 mr-3 text-neutral-400 group-hover:text-neutral-500"*/}
|
||||
{/* aria-hidden="true"*/}
|
||||
{/* />*/}
|
||||
{/* Duplicate*/}
|
||||
|
@ -344,7 +356,7 @@ export default function Availability({ user, types }) {
|
|||
{/* "group flex items-center px-4 py-2 text-sm font-medium"*/}
|
||||
{/* )}>*/}
|
||||
{/* <TrashIcon*/}
|
||||
{/* className="mr-3 h-5 w-5 text-red-400 group-hover:text-red-700"*/}
|
||||
{/* className="w-5 h-5 mr-3 text-red-400 group-hover:text-red-700"*/}
|
||||
{/* aria-hidden="true"*/}
|
||||
{/* />*/}
|
||||
{/* Delete*/}
|
||||
|
@ -367,7 +379,7 @@ export default function Availability({ user, types }) {
|
|||
{types.length === 0 && (
|
||||
<div className="md:py-20">
|
||||
<svg
|
||||
className="w-1/2 md:w-32 mx-auto block mb-4"
|
||||
className="block w-1/2 mx-auto mb-4 md:w-32"
|
||||
viewBox="0 0 132 132"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
|
@ -604,7 +616,7 @@ export default function Availability({ user, types }) {
|
|||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<div className="text-center block md:max-w-screen-sm mx-auto">
|
||||
<div className="block mx-auto text-center md:max-w-screen-sm">
|
||||
<h3 className="mt-2 text-xl font-bold text-neutral-900">Create your first event type</h3>
|
||||
<p className="mt-1 text-md text-neutral-600">
|
||||
Event types enable you to share links that show available times on your calendar and allow
|
||||
|
|
66
pages/sandbox/Button.tsx
Normal file
66
pages/sandbox/Button.tsx
Normal file
|
@ -0,0 +1,66 @@
|
|||
import { Button, ButtonProps } from "@components/ui/Button";
|
||||
import { PlusIcon } from "@heroicons/react/solid";
|
||||
import Head from "next/head";
|
||||
import React from "react";
|
||||
|
||||
export default function ButtonPage() {
|
||||
const list: ButtonProps[] = [
|
||||
// primary
|
||||
{ color: "primary" },
|
||||
{ color: "primary", disabled: true },
|
||||
{ color: "primary", disabled: true, loading: true },
|
||||
|
||||
// secondary
|
||||
{ color: "secondary" },
|
||||
{ color: "secondary", disabled: true },
|
||||
{ color: "secondary", disabled: true, loading: true },
|
||||
|
||||
// minimal
|
||||
{ color: "minimal" },
|
||||
{ color: "minimal", disabled: true },
|
||||
{ color: "minimal", disabled: true, loading: true },
|
||||
|
||||
// sizes
|
||||
{ color: "primary", size: "sm" },
|
||||
{ color: "primary", size: "base" },
|
||||
{ color: "primary", size: "lg" },
|
||||
|
||||
// href
|
||||
{ href: "/staging" },
|
||||
{ href: "/staging", disabled: true },
|
||||
|
||||
{ StartIcon: PlusIcon },
|
||||
{ EndIcon: PlusIcon },
|
||||
];
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<meta name="googlebot" content="noindex" />
|
||||
</Head>
|
||||
<div className="p-4 bg-gray-200">
|
||||
<h1>Button component</h1>
|
||||
<div className="flex flex-col">
|
||||
{list.map((props, index) => (
|
||||
<div key={index} className="p-2 m-2 bg-white">
|
||||
<h3>
|
||||
<code>
|
||||
{JSON.stringify(
|
||||
props,
|
||||
(key, value) => {
|
||||
if (key.includes("Icon")) {
|
||||
return "..";
|
||||
}
|
||||
return value;
|
||||
},
|
||||
2
|
||||
)}
|
||||
</code>
|
||||
</h3>
|
||||
<Button {...props}>Button text</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -4804,7 +4804,7 @@ next-transpile-modules@^8.0.0:
|
|||
enhanced-resolve "^5.7.0"
|
||||
escalade "^3.1.1"
|
||||
|
||||
next@^10.2.0:
|
||||
next@^10.2.3:
|
||||
version "10.2.3"
|
||||
resolved "https://registry.npmjs.org/next/-/next-10.2.3.tgz#5aa058a63626338cea91c198fda8f2715c058394"
|
||||
integrity sha512-dkM1mIfnORtGyzw/Yme8RdqNxlCMZyi4Lqj56F01/yHbe1ZtOaJ0cyqqRB4RGiPhjGGh0319f8ddjDyO1605Ow==
|
||||
|
|
Loading…
Reference in a new issue