Skip to content

Instantly share code, notes, and snippets.

@haris-aqeel
Created June 2, 2023 15:55
Show Gist options
  • Save haris-aqeel/c7fe2123d7471248b8fd31c9b928c6f1 to your computer and use it in GitHub Desktop.
Save haris-aqeel/c7fe2123d7471248b8fd31c9b928c6f1 to your computer and use it in GitHub Desktop.
/*
This example requires some changes to your config:
```
// tailwind.config.js
module.exports = {
// ...
plugins: [
// ...
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
require('@tailwindcss/aspect-ratio'),
],
}
```
*/
import { Fragment, useState } from 'react'
import { Dialog, Popover, Tab, Transition } from '@headlessui/react'
import { Bars3Icon, MagnifyingGlassIcon, ShoppingBagIcon, XMarkIcon } from '@heroicons/react/24/outline'
import { StarIcon } from '@heroicons/react/20/solid'
const navigation = {
categories: [
{
id: 'wireframe',
name: 'Wireframe Kits',
featured: [
{
name: 'Scaffold',
href: '#',
imageSrc: 'https://tailwindui.com/img/ecommerce-images/product-page-05-menu-03.jpg',
imageAlt:
'Pricing page screenshot with tiered plan options and comparison table on colorful blue and green background.',
},
{
name: 'Bones',
href: '#',
imageSrc: 'https://tailwindui.com/img/ecommerce-images/product-page-05-menu-04.jpg',
imageAlt:
'Application screenshot with tiered navigation and account settings form on color red and purple background.',
},
],
sections: [
{
id: 'application',
name: 'Application UI',
items: [
{ name: 'Home Screens', href: '#' },
{ name: 'Detail Screens', href: '#' },
{ name: 'Settings Screens', href: '#' },
],
},
{
id: 'marketing',
name: 'Marketing',
items: [
{ name: 'Landing Pages', href: '#' },
{ name: 'Pricing Pages', href: '#' },
{ name: 'Contact Pages', href: '#' },
],
},
{
id: 'ecommerce',
name: 'Ecommerce',
items: [
{ name: 'Storefront Pages', href: '#' },
{ name: 'Product Pages', href: '#' },
{ name: 'Category Pages', href: '#' },
{ name: 'Shopping Cart Pages', href: '#' },
{ name: 'Checkout Pages', href: '#' },
],
},
],
},
{
id: 'icons',
name: 'Icons',
featured: [
{
name: 'Application UI Pack',
href: '#',
imageSrc: 'https://tailwindui.com/img/ecommerce-images/product-page-05-menu-01.jpg',
imageAlt:
'Payment application dashboard screenshot with transaction table, financial highlights, and main clients on colorful purple background.',
},
{
name: 'Marketing Icon Pack',
href: '#',
imageSrc: 'https://tailwindui.com/img/ecommerce-images/product-page-05-menu-02.jpg',
imageAlt: 'Calendar user interface screenshot with icon buttons and orange-yellow theme.',
},
],
sections: [
{
id: 'general',
name: 'General Use',
items: [
{ name: 'Heroicons Solid', href: '#' },
{ name: 'Heroicons Outline', href: '#' },
{ name: 'Line Illustrations', href: '#' },
{ name: 'Hero Illustrations', href: '#' },
{ name: 'Branded Illustrations', href: '#' },
{ name: 'Skeuomorphic Illustrations', href: '#' },
{ name: 'Hand Drawn Illustrations', href: '#' },
],
},
{
id: 'application',
name: 'Application UI',
items: [
{ name: 'Outlined', href: '#' },
{ name: 'Solid', href: '#' },
{ name: 'Branded', href: '#' },
{ name: 'Small', href: '#' },
{ name: 'Illustrations', href: '#' },
],
},
{
id: 'marketing',
name: 'Marketing',
items: [
{ name: 'Outlined', href: '#' },
{ name: 'Solid', href: '#' },
{ name: 'Branded', href: '#' },
{ name: 'Small', href: '#' },
{ name: 'Illustrations', href: '#' },
],
},
],
},
],
pages: [
{ name: 'UI Kits', href: '#' },
{ name: 'Themes', href: '#' },
],
}
const product = {
name: 'Application UI Icon Pack',
version: { name: '1.0', date: 'June 5, 2021', datetime: '2021-06-05' },
price: '$220',
description:
'The Application UI Icon Pack comes with over 200 icons in 3 styles: outline, filled, and branded. This playful icon pack is tailored for complex application user interfaces with a friendly and legible look.',
highlights: [
'200+ SVG icons in 3 unique styles',
'Compatible with Figma, Sketch, and Adobe XD',
'Drawn on 24 x 24 pixel grid',
],
imageSrc: 'https://tailwindui.com/img/ecommerce-images/product-page-05-product-01.jpg',
imageAlt: 'Sample of 30 icons with friendly and fun details in outline, filled, and brand color styles.',
}
const reviews = {
average: 4,
featured: [
{
id: 1,
rating: 5,
content: `
<p>This icon pack is just what I need for my latest project. There's an icon for just about anything I could ever need. Love the playful look!</p>
`,
date: 'July 16, 2021',
datetime: '2021-07-16',
author: 'Emily Selman',
avatarSrc:
'https://images.unsplash.com/photo-1502685104226-ee32379fefbe?ixlib=rb-=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=8&w=256&h=256&q=80',
},
{
id: 2,
rating: 5,
content: `
<p>Blown away by how polished this icon pack is. Everything looks so consistent and each SVG is optimized out of the box so I can use it directly with confidence. It would take me several hours to create a single icon this good, so it's a steal at this price.</p>
`,
date: 'July 12, 2021',
datetime: '2021-07-12',
author: 'Hector Gibbons',
avatarSrc:
'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=8&w=256&h=256&q=80',
},
// More reviews...
],
}
const faqs = [
{
question: 'What format are these icons?',
answer:
'The icons are in SVG (Scalable Vector Graphic) format. They can be imported into your design tool of choice and used directly in code.',
},
{
question: 'Can I use the icons at different sizes?',
answer:
"Yes. The icons are drawn on a 24 x 24 pixel grid, but the icons can be scaled to different sizes as needed. We don't recommend going smaller than 20 x 20 or larger than 64 x 64 to retain legibility and visual balance.",
},
// More FAQs...
]
const license = {
href: '#',
summary:
'For personal and professional use. You cannot resell or redistribute these icons in their original or modified state.',
content: `
<h4>Overview</h4>
<p>For personal and professional use. You cannot resell or redistribute these icons in their original or modified state.</p>
<ul role="list">
<li>You\'re allowed to use the icons in unlimited projects.</li>
<li>Attribution is not required to use the icons.</li>
</ul>
<h4>What you can do with it</h4>
<ul role="list">
<li>Use them freely in your personal and professional work.</li>
<li>Make them your own. Change the colors to suit your project or brand.</li>
</ul>
<h4>What you can\'t do with it</h4>
<ul role="list">
<li>Don\'t be greedy. Selling or distributing these icons in their original or modified state is prohibited.</li>
<li>Don\'t be evil. These icons cannot be used on websites or applications that promote illegal or immoral beliefs or activities.</li>
</ul>
`,
}
const relatedProducts = [
{
id: 1,
name: 'Fusion',
category: 'UI Kit',
href: '#',
price: '$49',
imageSrc: 'https://tailwindui.com/img/ecommerce-images/product-page-05-related-product-01.jpg',
imageAlt:
'Payment application dashboard screenshot with transaction table, financial highlights, and main clients on colorful purple background.',
},
// More products...
]
const footerNavigation = {
products: [
{ name: 'Wireframe Kits', href: '#' },
{ name: 'Icons', href: '#' },
{ name: 'UI Kits', href: '#' },
{ name: 'Themes', href: '#' },
],
company: [
{ name: 'Who we are', href: '#' },
{ name: 'Open Source', href: '#' },
{ name: 'Press', href: '#' },
{ name: 'Careers', href: '#' },
{ name: 'License', href: '#' },
{ name: 'Privacy', href: '#' },
],
customerService: [
{ name: 'Chat', href: '#' },
{ name: 'Contact', href: '#' },
{ name: 'Secure Payments', href: '#' },
{ name: 'FAQ', href: '#' },
],
}
function classNames(...classes) {
return classes.filter(Boolean).join(' ')
}
export default function Example() {
const [open, setOpen] = useState(false)
return (
<div className="bg-white">
{/* Mobile menu */}
<Transition.Root show={open} as={Fragment}>
<Dialog as="div" className="relative z-40 lg:hidden" onClose={setOpen}>
<Transition.Child
as={Fragment}
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>
<div className="fixed inset-0 z-40 flex">
<Transition.Child
as={Fragment}
enter="transition ease-in-out duration-300 transform"
enterFrom="-translate-x-full"
enterTo="translate-x-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="translate-x-0"
leaveTo="-translate-x-full"
>
<Dialog.Panel className="relative flex w-full max-w-xs flex-col overflow-y-auto bg-white pb-12 shadow-xl">
<div className="flex px-4 pb-2 pt-5">
<button
type="button"
className="-m-2 inline-flex items-center justify-center rounded-md p-2 text-gray-400"
onClick={() => setOpen(false)}
>
<span className="sr-only">Close menu</span>
<XMarkIcon className="h-6 w-6" aria-hidden="true" />
</button>
</div>
{/* Links */}
<Tab.Group as="div" className="mt-2">
<div className="border-b border-gray-200">
<Tab.List className="-mb-px flex space-x-8 px-4">
{navigation.categories.map((category) => (
<Tab
key={category.name}
className={({ selected }) =>
classNames(
selected ? 'border-indigo-600 text-indigo-600' : 'border-transparent text-gray-900',
'flex-1 whitespace-nowrap border-b-2 px-1 py-4 text-base font-medium'
)
}
>
{category.name}
</Tab>
))}
</Tab.List>
</div>
<Tab.Panels as={Fragment}>
{navigation.categories.map((category) => (
<Tab.Panel key={category.name} className="space-y-10 px-4 pb-8 pt-10">
<div className="grid grid-cols-2 gap-x-4">
{category.featured.map((item) => (
<div key={item.name} className="group relative text-sm">
<div className="aspect-h-1 aspect-w-1 overflow-hidden rounded-lg bg-gray-100 group-hover:opacity-75">
<img src={item.imageSrc} alt={item.imageAlt} className="object-cover object-center" />
</div>
<a href={item.href} className="mt-6 block font-medium text-gray-900">
<span className="absolute inset-0 z-10" aria-hidden="true" />
{item.name}
</a>
<p aria-hidden="true" className="mt-1">
Shop now
</p>
</div>
))}
</div>
{category.sections.map((section) => (
<div key={section.name}>
<p id={`${category.id}-${section.id}-heading-mobile`} className="font-medium text-gray-900">
{section.name}
</p>
<ul
role="list"
aria-labelledby={`${category.id}-${section.id}-heading-mobile`}
className="mt-6 flex flex-col space-y-6"
>
{section.items.map((item) => (
<li key={item.name} className="flow-root">
<a href={item.href} className="-m-2 block p-2 text-gray-500">
{item.name}
</a>
</li>
))}
</ul>
</div>
))}
</Tab.Panel>
))}
</Tab.Panels>
</Tab.Group>
<div className="space-y-6 border-t border-gray-200 px-4 py-6">
{navigation.pages.map((page) => (
<div key={page.name} className="flow-root">
<a href={page.href} className="-m-2 block p-2 font-medium text-gray-900">
{page.name}
</a>
</div>
))}
</div>
<div className="space-y-6 border-t border-gray-200 px-4 py-6">
<div className="flow-root">
<a href="#" className="-m-2 block p-2 font-medium text-gray-900">
Sign in
</a>
</div>
<div className="flow-root">
<a href="#" className="-m-2 block p-2 font-medium text-gray-900">
Create account
</a>
</div>
</div>
<div className="border-t border-gray-200 px-4 py-6">
<a href="#" className="-m-2 flex items-center p-2">
<img
src="https://tailwindui.com/img/flags/flag-canada.svg"
alt=""
className="block h-auto w-5 flex-shrink-0"
/>
<span className="ml-3 block text-base font-medium text-gray-900">CAD</span>
<span className="sr-only">, change currency</span>
</a>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</Dialog>
</Transition.Root>
<header className="relative bg-white">
<p className="flex h-10 items-center justify-center bg-indigo-600 px-4 text-sm font-medium text-white sm:px-6 lg:px-8">
Save 20% when you buy two or more kits
</p>
<nav aria-label="Top" className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="border-b border-gray-200">
<div className="flex h-16 items-center">
<button
type="button"
className="rounded-md bg-white p-2 text-gray-400 lg:hidden"
onClick={() => setOpen(true)}
>
<span className="sr-only">Open menu</span>
<Bars3Icon className="h-6 w-6" aria-hidden="true" />
</button>
{/* Logo */}
<div className="ml-4 flex lg:ml-0">
<a href="#">
<span className="sr-only">Your Company</span>
<img
className="h-8 w-auto"
src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600"
alt=""
/>
</a>
</div>
{/* Flyout menus */}
<Popover.Group className="hidden lg:ml-8 lg:block lg:self-stretch">
<div className="flex h-full space-x-8">
{navigation.categories.map((category) => (
<Popover key={category.name} className="flex">
{({ open }) => (
<>
<div className="relative flex">
<Popover.Button
className={classNames(
open
? 'border-indigo-600 text-indigo-600'
: 'border-transparent text-gray-700 hover:text-gray-800',
'relative z-10 -mb-px flex items-center border-b-2 pt-px text-sm font-medium transition-colors duration-200 ease-out'
)}
>
{category.name}
</Popover.Button>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition ease-in duration-150"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Popover.Panel className="absolute inset-x-0 top-full z-10 text-sm text-gray-500">
{/* Presentational element used to render the bottom shadow, if we put the shadow on the actual panel it pokes out the top, so we use this shorter element to hide the top of the shadow */}
<div className="absolute inset-0 top-1/2 bg-white shadow" aria-hidden="true" />
<div className="relative bg-white">
<div className="mx-auto max-w-7xl px-8">
<div className="grid grid-cols-2 gap-x-8 gap-y-10 py-16">
<div className="col-start-2 grid grid-cols-2 gap-x-8">
{category.featured.map((item) => (
<div key={item.name} className="group relative text-base sm:text-sm">
<div className="aspect-h-1 aspect-w-1 overflow-hidden rounded-lg bg-gray-100 group-hover:opacity-75">
<img
src={item.imageSrc}
alt={item.imageAlt}
className="object-cover object-center"
/>
</div>
<a href={item.href} className="mt-6 block font-medium text-gray-900">
<span className="absolute inset-0 z-10" aria-hidden="true" />
{item.name}
</a>
<p aria-hidden="true" className="mt-1">
Shop now
</p>
</div>
))}
</div>
<div className="row-start-1 grid grid-cols-3 gap-x-8 gap-y-10 text-sm">
{category.sections.map((section) => (
<div key={section.name}>
<p id={`${section.id}-heading`} className="font-medium text-gray-900">
{section.name}
</p>
<ul
role="list"
aria-labelledby={`${section.id}-heading`}
className="mt-6 space-y-6 sm:mt-4 sm:space-y-4"
>
{section.items.map((item) => (
<li key={item.name} className="flex">
<a href={item.href} className="hover:text-gray-800">
{item.name}
</a>
</li>
))}
</ul>
</div>
))}
</div>
</div>
</div>
</div>
</Popover.Panel>
</Transition>
</>
)}
</Popover>
))}
{navigation.pages.map((page) => (
<a
key={page.name}
href={page.href}
className="flex items-center text-sm font-medium text-gray-700 hover:text-gray-800"
>
{page.name}
</a>
))}
</div>
</Popover.Group>
<div className="ml-auto flex items-center">
<div className="hidden lg:flex lg:flex-1 lg:items-center lg:justify-end lg:space-x-6">
<a href="#" className="text-sm font-medium text-gray-700 hover:text-gray-800">
Sign in
</a>
<span className="h-6 w-px bg-gray-200" aria-hidden="true" />
<a href="#" className="text-sm font-medium text-gray-700 hover:text-gray-800">
Create account
</a>
</div>
<div className="hidden lg:ml-8 lg:flex">
<a href="#" className="flex items-center text-gray-700 hover:text-gray-800">
<img
src="https://tailwindui.com/img/flags/flag-canada.svg"
alt=""
className="block h-auto w-5 flex-shrink-0"
/>
<span className="ml-3 block text-sm font-medium">CAD</span>
<span className="sr-only">, change currency</span>
</a>
</div>
{/* Search */}
<div className="flex lg:ml-6">
<a href="#" className="p-2 text-gray-400 hover:text-gray-500">
<span className="sr-only">Search</span>
<MagnifyingGlassIcon className="h-6 w-6" aria-hidden="true" />
</a>
</div>
{/* Cart */}
<div className="ml-4 flow-root lg:ml-6">
<a href="#" className="group -m-2 flex items-center p-2">
<ShoppingBagIcon
className="h-6 w-6 flex-shrink-0 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
<span className="ml-2 text-sm font-medium text-gray-700 group-hover:text-gray-800">0</span>
<span className="sr-only">items in cart, view bag</span>
</a>
</div>
</div>
</div>
</div>
</nav>
</header>
<main className="mx-auto px-4 pb-24 pt-14 sm:px-6 sm:pb-32 sm:pt-16 lg:max-w-7xl lg:px-8">
{/* Product */}
<div className="lg:grid lg:grid-cols-7 lg:grid-rows-1 lg:gap-x-8 lg:gap-y-10 xl:gap-x-16">
{/* Product image */}
<div className="lg:col-span-4 lg:row-end-1">
<div className="aspect-h-3 aspect-w-4 overflow-hidden rounded-lg bg-gray-100">
<img src={product.imageSrc} alt={product.imageAlt} className="object-cover object-center" />
</div>
</div>
{/* Product details */}
<div className="mx-auto mt-14 max-w-2xl sm:mt-16 lg:col-span-3 lg:row-span-2 lg:row-end-2 lg:mt-0 lg:max-w-none">
<div className="flex flex-col-reverse">
<div className="mt-4">
<h1 className="text-2xl font-bold tracking-tight text-gray-900 sm:text-3xl">{product.name}</h1>
<h2 id="information-heading" className="sr-only">
Product information
</h2>
<p className="mt-2 text-sm text-gray-500">
Version {product.version.name} (Updated{' '}
<time dateTime={product.version.datetime}>{product.version.date}</time>)
</p>
</div>
<div>
<h3 className="sr-only">Reviews</h3>
<div className="flex items-center">
{[0, 1, 2, 3, 4].map((rating) => (
<StarIcon
key={rating}
className={classNames(
reviews.average > rating ? 'text-yellow-400' : 'text-gray-300',
'h-5 w-5 flex-shrink-0'
)}
aria-hidden="true"
/>
))}
</div>
<p className="sr-only">{reviews.average} out of 5 stars</p>
</div>
</div>
<p className="mt-6 text-gray-500">{product.description}</p>
<div className="mt-10 grid grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2">
<button
type="button"
className="flex w-full items-center justify-center rounded-md border border-transparent bg-indigo-600 px-8 py-3 text-base font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:ring-offset-gray-50"
>
Pay {product.price}
</button>
<button
type="button"
className="flex w-full items-center justify-center rounded-md border border-transparent bg-indigo-50 px-8 py-3 text-base font-medium text-indigo-700 hover:bg-indigo-100 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:ring-offset-gray-50"
>
Preview
</button>
</div>
<div className="mt-10 border-t border-gray-200 pt-10">
<h3 className="text-sm font-medium text-gray-900">Highlights</h3>
<div className="prose prose-sm mt-4 text-gray-500">
<ul role="list">
{product.highlights.map((highlight) => (
<li key={highlight}>{highlight}</li>
))}
</ul>
</div>
</div>
<div className="mt-10 border-t border-gray-200 pt-10">
<h3 className="text-sm font-medium text-gray-900">License</h3>
<p className="mt-4 text-sm text-gray-500">
{license.summary}{' '}
<a href={license.href} className="font-medium text-indigo-600 hover:text-indigo-500">
Read full license
</a>
</p>
</div>
<div className="mt-10 border-t border-gray-200 pt-10">
<h3 className="text-sm font-medium text-gray-900">Share</h3>
<ul role="list" className="mt-4 flex items-center space-x-6">
<li>
<a href="#" className="flex h-6 w-6 items-center justify-center text-gray-400 hover:text-gray-500">
<span className="sr-only">Share on Facebook</span>
<svg className="h-5 w-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M20 10c0-5.523-4.477-10-10-10S0 4.477 0 10c0 4.991 3.657 9.128 8.438 9.878v-6.987h-2.54V10h2.54V7.797c0-2.506 1.492-3.89 3.777-3.89 1.094 0 2.238.195 2.238.195v2.46h-1.26c-1.243 0-1.63.771-1.63 1.562V10h2.773l-.443 2.89h-2.33v6.988C16.343 19.128 20 14.991 20 10z"
clipRule="evenodd"
/>
</svg>
</a>
</li>
<li>
<a href="#" className="flex h-6 w-6 items-center justify-center text-gray-400 hover:text-gray-500">
<span className="sr-only">Share on Instagram</span>
<svg className="h-6 w-6" aria-hidden="true" fill="currentColor" viewBox="0 0 24 24">
<path
fillRule="evenodd"
d="M12.315 2c2.43 0 2.784.013 3.808.06 1.064.049 1.791.218 2.427.465a4.902 4.902 0 011.772 1.153 4.902 4.902 0 011.153 1.772c.247.636.416 1.363.465 2.427.048 1.067.06 1.407.06 4.123v.08c0 2.643-.012 2.987-.06 4.043-.049 1.064-.218 1.791-.465 2.427a4.902 4.902 0 01-1.153 1.772 4.902 4.902 0 01-1.772 1.153c-.636.247-1.363.416-2.427.465-1.067.048-1.407.06-4.123.06h-.08c-2.643 0-2.987-.012-4.043-.06-1.064-.049-1.791-.218-2.427-.465a4.902 4.902 0 01-1.772-1.153 4.902 4.902 0 01-1.153-1.772c-.247-.636-.416-1.363-.465-2.427-.047-1.024-.06-1.379-.06-3.808v-.63c0-2.43.013-2.784.06-3.808.049-1.064.218-1.791.465-2.427a4.902 4.902 0 011.153-1.772A4.902 4.902 0 015.45 2.525c.636-.247 1.363-.416 2.427-.465C8.901 2.013 9.256 2 11.685 2h.63zm-.081 1.802h-.468c-2.456 0-2.784.011-3.807.058-.975.045-1.504.207-1.857.344-.467.182-.8.398-1.15.748-.35.35-.566.683-.748 1.15-.137.353-.3.882-.344 1.857-.047 1.023-.058 1.351-.058 3.807v.468c0 2.456.011 2.784.058 3.807.045.975.207 1.504.344 1.857.182.466.399.8.748 1.15.35.35.683.566 1.15.748.353.137.882.3 1.857.344 1.054.048 1.37.058 4.041.058h.08c2.597 0 2.917-.01 3.96-.058.976-.045 1.505-.207 1.858-.344.466-.182.8-.398 1.15-.748.35-.35.566-.683.748-1.15.137-.353.3-.882.344-1.857.048-1.055.058-1.37.058-4.041v-.08c0-2.597-.01-2.917-.058-3.96-.045-.976-.207-1.505-.344-1.858a3.097 3.097 0 00-.748-1.15 3.098 3.098 0 00-1.15-.748c-.353-.137-.882-.3-1.857-.344-1.023-.047-1.351-.058-3.807-.058zM12 6.865a5.135 5.135 0 110 10.27 5.135 5.135 0 010-10.27zm0 1.802a3.333 3.333 0 100 6.666 3.333 3.333 0 000-6.666zm5.338-3.205a1.2 1.2 0 110 2.4 1.2 1.2 0 010-2.4z"
clipRule="evenodd"
/>
</svg>
</a>
</li>
<li>
<a href="#" className="flex h-6 w-6 items-center justify-center text-gray-400 hover:text-gray-500">
<span className="sr-only">Share on Twitter</span>
<svg className="h-5 w-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path d="M6.29 18.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0020 3.92a8.19 8.19 0 01-2.357.646 4.118 4.118 0 001.804-2.27 8.224 8.224 0 01-2.605.996 4.107 4.107 0 00-6.993 3.743 11.65 11.65 0 01-8.457-4.287 4.106 4.106 0 001.27 5.477A4.073 4.073 0 01.8 7.713v.052a4.105 4.105 0 003.292 4.022 4.095 4.095 0 01-1.853.07 4.108 4.108 0 003.834 2.85A8.233 8.233 0 010 16.407a11.616 11.616 0 006.29 1.84" />
</svg>
</a>
</li>
</ul>
</div>
</div>
<div className="mx-auto mt-16 w-full max-w-2xl lg:col-span-4 lg:mt-0 lg:max-w-none">
<Tab.Group as="div">
<div className="border-b border-gray-200">
<Tab.List className="-mb-px flex space-x-8">
<Tab
className={({ selected }) =>
classNames(
selected
? 'border-indigo-600 text-indigo-600'
: 'border-transparent text-gray-700 hover:border-gray-300 hover:text-gray-800',
'whitespace-nowrap border-b-2 py-6 text-sm font-medium'
)
}
>
Customer Reviews
</Tab>
<Tab
className={({ selected }) =>
classNames(
selected
? 'border-indigo-600 text-indigo-600'
: 'border-transparent text-gray-700 hover:border-gray-300 hover:text-gray-800',
'whitespace-nowrap border-b-2 py-6 text-sm font-medium'
)
}
>
FAQ
</Tab>
<Tab
className={({ selected }) =>
classNames(
selected
? 'border-indigo-600 text-indigo-600'
: 'border-transparent text-gray-700 hover:border-gray-300 hover:text-gray-800',
'whitespace-nowrap border-b-2 py-6 text-sm font-medium'
)
}
>
License
</Tab>
</Tab.List>
</div>
<Tab.Panels as={Fragment}>
<Tab.Panel className="-mb-10">
<h3 className="sr-only">Customer Reviews</h3>
{reviews.featured.map((review, reviewIdx) => (
<div key={review.id} className="flex space-x-4 text-sm text-gray-500">
<div className="flex-none py-10">
<img src={review.avatarSrc} alt="" className="h-10 w-10 rounded-full bg-gray-100" />
</div>
<div className={classNames(reviewIdx === 0 ? '' : 'border-t border-gray-200', 'flex-1 py-10')}>
<h3 className="font-medium text-gray-900">{review.author}</h3>
<p>
<time dateTime={review.datetime}>{review.date}</time>
</p>
<div className="mt-4 flex items-center">
{[0, 1, 2, 3, 4].map((rating) => (
<StarIcon
key={rating}
className={classNames(
review.rating > rating ? 'text-yellow-400' : 'text-gray-300',
'h-5 w-5 flex-shrink-0'
)}
aria-hidden="true"
/>
))}
</div>
<p className="sr-only">{review.rating} out of 5 stars</p>
<div
className="prose prose-sm mt-4 max-w-none text-gray-500"
dangerouslySetInnerHTML={{ __html: review.content }}
/>
</div>
</div>
))}
</Tab.Panel>
<Tab.Panel className="text-sm text-gray-500">
<h3 className="sr-only">Frequently Asked Questions</h3>
<dl>
{faqs.map((faq) => (
<Fragment key={faq.question}>
<dt className="mt-10 font-medium text-gray-900">{faq.question}</dt>
<dd className="prose prose-sm mt-2 max-w-none text-gray-500">
<p>{faq.answer}</p>
</dd>
</Fragment>
))}
</dl>
</Tab.Panel>
<Tab.Panel className="pt-10">
<h3 className="sr-only">License</h3>
<div
className="prose prose-sm max-w-none text-gray-500"
dangerouslySetInnerHTML={{ __html: license.content }}
/>
</Tab.Panel>
</Tab.Panels>
</Tab.Group>
</div>
</div>
{/* Related products */}
<div className="mx-auto mt-24 max-w-2xl sm:mt-32 lg:max-w-none">
<div className="flex items-center justify-between space-x-4">
<h2 className="text-lg font-medium text-gray-900">Customers also viewed</h2>
<a href="#" className="whitespace-nowrap text-sm font-medium text-indigo-600 hover:text-indigo-500">
View all
<span aria-hidden="true"> &rarr;</span>
</a>
</div>
<div className="mt-6 grid grid-cols-1 gap-x-8 gap-y-8 sm:grid-cols-2 sm:gap-y-10 lg:grid-cols-4">
{relatedProducts.map((product) => (
<div key={product.id} className="group relative">
<div className="aspect-h-3 aspect-w-4 overflow-hidden rounded-lg bg-gray-100">
<img src={product.imageSrc} alt={product.imageAlt} className="object-cover object-center" />
<div className="flex items-end p-4 opacity-0 group-hover:opacity-100" aria-hidden="true">
<div className="w-full rounded-md bg-white bg-opacity-75 px-4 py-2 text-center text-sm font-medium text-gray-900 backdrop-blur backdrop-filter">
View Product
</div>
</div>
</div>
<div className="mt-4 flex items-center justify-between space-x-8 text-base font-medium text-gray-900">
<h3>
<a href="#">
<span aria-hidden="true" className="absolute inset-0" />
{product.name}
</a>
</h3>
<p>{product.price}</p>
</div>
<p className="mt-1 text-sm text-gray-500">{product.category}</p>
</div>
))}
</div>
</div>
</main>
<footer aria-labelledby="footer-heading" className="bg-gray-50">
<h2 id="footer-heading" className="sr-only">
Footer
</h2>
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="grid grid-cols-1 py-20 md:grid-flow-col md:auto-rows-min md:grid-cols-12 md:gap-x-8 md:gap-y-16">
{/* Image section */}
<div className="col-span-1 md:col-span-2 lg:col-start-1 lg:row-start-1">
<img
src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600"
alt=""
className="h-8 w-auto"
/>
</div>
{/* Sitemap sections */}
<div className="col-span-6 mt-10 grid grid-cols-2 gap-8 sm:grid-cols-3 md:col-span-8 md:col-start-3 md:row-start-1 md:mt-0 lg:col-span-6 lg:col-start-2">
<div className="grid grid-cols-1 gap-y-12 sm:col-span-2 sm:grid-cols-2 sm:gap-x-8">
<div>
<h3 className="text-sm font-medium text-gray-900">Products</h3>
<ul role="list" className="mt-6 space-y-6">
{footerNavigation.products.map((item) => (
<li key={item.name} className="text-sm">
<a href={item.href} className="text-gray-500 hover:text-gray-600">
{item.name}
</a>
</li>
))}
</ul>
</div>
<div>
<h3 className="text-sm font-medium text-gray-900">Company</h3>
<ul role="list" className="mt-6 space-y-6">
{footerNavigation.company.map((item) => (
<li key={item.name} className="text-sm">
<a href={item.href} className="text-gray-500 hover:text-gray-600">
{item.name}
</a>
</li>
))}
</ul>
</div>
</div>
<div>
<h3 className="text-sm font-medium text-gray-900">Customer Service</h3>
<ul role="list" className="mt-6 space-y-6">
{footerNavigation.customerService.map((item) => (
<li key={item.name} className="text-sm">
<a href={item.href} className="text-gray-500 hover:text-gray-600">
{item.name}
</a>
</li>
))}
</ul>
</div>
</div>
{/* Newsletter section */}
<div className="mt-12 md:col-span-8 md:col-start-3 md:row-start-2 md:mt-0 lg:col-span-4 lg:col-start-9 lg:row-start-1">
<h3 className="text-sm font-medium text-gray-900">Sign up for our newsletter</h3>
<p className="mt-1 text-sm text-gray-500">Be the first to know when we release new products.</p>
<form className="mt-3 sm:flex lg:block xl:flex">
<label htmlFor="email-address" className="sr-only">
Email address
</label>
<input
id="email-address"
type="text"
autoComplete="email"
required
className="block w-full rounded-md border border-gray-300 bg-white px-4 py-2 text-base text-gray-900 placeholder-gray-500 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 sm:min-w-0 sm:max-w-xs sm:flex-1 lg:max-w-none"
/>
<div className="mt-4 sm:ml-4 sm:mt-0 sm:flex-shrink-0 lg:ml-0 lg:mt-4 xl:ml-4 xl:mt-0">
<button
type="submit"
className="flex w-full items-center justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
>
Sign up
</button>
</div>
</form>
</div>
</div>
<div className="border-t border-gray-200 py-10 text-center">
<p className="text-sm text-gray-500">&copy; 2021 Your Company, Inc.</p>
</div>
</div>
</footer>
</div>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment