Skip to content
This repository was archived by the owner on Feb 15, 2022. It is now read-only.

Bind to HeadlessUI to implement Flyout menus #385

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
83 changes: 83 additions & 0 deletions bindings/headlessui/Headlessui.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
module Popover = {
type popoverChildrenRenderProps = {@as("open") open_: bool}

@module("@headlessui/react") @react.component
external make: (
~as_: string=?,
~children: popoverChildrenRenderProps => React.element=?,
~className: string=?,
) => React.element = "Popover"

module Overlay = {
@module("@headlessui/react") @scope("Popover") @react.component
external make: (~as_: string=?, ~children: 'children=?, ~className: string=?) => React.element =
"Overlay"
}

module Button = {
@module("@headlessui/react") @scope("Popover") @react.component
external make: (~as_: string=?, ~children: 'children=?, ~className: string=?) => React.element =
"Button"
}

module Panel = {
@module("@headlessui/react") @scope("Popover") @react.component
external make: (
~as_: string=?,
~focus: bool=?,
~static: bool=?,
~unmount: bool=?,
~children: 'children=?,
~className: string=?,
) => React.element = "Panel"
}

module Group = {
@module("@headlessui/react") @scope("Popover") @react.component
external make: (~as_: string=?, ~children: 'children=?, ~className: string=?) => React.element =
"Group"
}
}

module Transition = {
@module("@headlessui/react") @react.component
external make: (
~show: bool,
~as_: string=?,
~appear: bool=?,
~unmount: bool=?,
~enter: string=?,
~enterFrom: string=?,
~enterTo: string=?,
~leave: string=?,
~leaveFrom: string=?,
~leaveTo: string=?,
~beforeEnter: unit => unit=?,
~afterEnter: unit => unit=?,
~beforeLeave: unit => unit=?,
~afterLeave: unit => unit=?,
~children: 'children=?,
~className: string=?,
) => React.element = "Transition"

module Child = {
@module("@headlessui/react") @scope("Transition") @react.component
external make: (
~as_: string=?,
~appear: bool=?,
~unmount: bool=?,
~enter: string=?,
~enterFrom: string=?,
~enterTo: string=?,
~leave: string=?,
~leaveFrom: string=?,
~leaveTo: string=?,
~beforeEnter: unit => unit=?,
~afterEnter: unit => unit=?,
~beforeLeave: unit => unit=?,
~afterLeave: unit => unit=?,
~children: 'children,
~className: string=?,
) => React.element = "Child"
}
}
4 changes: 4 additions & 0 deletions bsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
{
"dir": "src"
},
{
"dir": "bindings",
"subdirs": true
},
{
"dir": "pages",
"subdirs": true
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"dependencies": {
"@glennsl/bs-json": "^5.0.2",
"@headlessui/react": "^1.2.0",
"@rescript/react": "^0.10.3",
"bs-platform": "9.0.2",
"next": "^10.2.0",
Expand Down
75 changes: 75 additions & 0 deletions src/FlyoutMenu.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
module Popover = Headlessui.Popover
module Transition = Headlessui.Transition
module Link = Next.Link

type item = {
name: string,
description: string,
href: string,
icon: React.element,
}

@react.component
let make = (~name, ~items) =>
<Popover className="relative">
{({open_}) => <>
<Popover.Button
className={(
open_ ? "text-gray-900 " : "text-gray-500 "
) ++ "group bg-white rounded-md inline-flex items-center text-base font-medium hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"}>
<span> {React.string(name)} </span>
<svg
className={(
open_ ? "text-gray-600 " : "text-gray-400 "
) ++ "ml-2 h-5 w-5 group-hover:text-gray-500"}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
ariaHidden=true>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</Popover.Button>
<Transition
show={open_}
as_={"div"}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1">
<Popover.Panel
static=true
className="absolute z-10 left-1/2 transform -translate-x-1/2 mt-3 px-2 w-screen max-w-md sm:px-0">
<div className="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 overflow-hidden">
<div className="relative grid gap-6 bg-white px-5 py-6 sm:gap-8 sm:p-8">
{Array.mapi(
(idx, item: NavEntry.t) =>
<Link href=item.url key={Js.Int.toString(idx)}>
<a
key={item.label}
href={item.url}
className="-m-3 p-3 flex items-start rounded-lg hover:bg-gray-50 transition ease-in-out duration-150">
<i className="flex-shrink-0 h-6 w-6 text-indigo-600" ariaHidden=true>
{item.icon}
</i>
<div className="ml-4">
<p className="text-base font-medium text-gray-900">
{React.string(item.label)}
</p>
<p className="mt-1 text-sm text-gray-500"> {React.string(item.text)} </p>
</div>
</a>
</Link>,
items,
)->React.array}
</div>
</div>
</Popover.Panel>
</Transition>
</>}
</Popover>
162 changes: 3 additions & 159 deletions src/HeaderNavigation.res
Original file line number Diff line number Diff line change
Expand Up @@ -52,165 +52,9 @@ let make = (~content) => {
</a>
</div>
<nav className="hidden md:flex space-x-10 ">
<div className="relative">
<button
onClick={toggleMenu(Principles)}
type_="button"
className="text-gray-500 pl-2 group bg-white rounded-md inline-flex items-center text-base font-medium hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orangedark"
ariaExpanded=false>
<span> {s(content.principlesSection.header)} </span>
<svg
className="text-gray-400 ml-2 h-5 w-5 group-hover:text-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
ariaHidden=true>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
<div
className={"absolute z-10 left-1/2 transform -translate-x-1/4 mt-3 px-2 w-screen max-w-sm sm:px-0 " ++
switch activeMenu {
| Some(Principles) => " opacity-100 translate-y-0 "
| _ => " hidden "
}}>
<div
className="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 overflow-hidden">
<div className="relative grid gap-6 bg-white px-5 py-6 sm:gap-6 sm:p-8">
{content.principlesSection.entries
|> Js.Array.mapi((e: NavEntry.t, idx) =>
<Link href=e.url key={Js.Int.toString(idx)}>
<a
onClick=hideMenu
className="-m-3 p-3 block rounded-md hover:bg-gray-50 transition ease-in-out duration-150">
<div
className="h-7 w-7 float-left fill-current stroke-current text-orangedark">
{e.icon}
</div>
<dt>
<p className="ml-10 text-sm font-semibold text-gray-900">
{s(e.label)}
</p>
</dt>
<dd className="ml-10 text-sm text-gray-500"> {s(e.text)} </dd>
</a>
</Link>
)
|> React.array}
</div>
</div>
</div>
</div>
<div className="relative">
<button
onClick={toggleMenu(Resources)}
type_="button"
className="text-gray-500 pl-2 group bg-white rounded-md inline-flex items-center text-base font-medium hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orangedark"
ariaExpanded=false>
<span> {s(content.resourcesSection.header)} </span>
<svg
className="text-gray-400 ml-2 h-5 w-5 group-hover:text-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
ariaHidden=true>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
<div
className={"absolute z-10 left-1/2 transform -translate-x-1/3 mt-3 px-2 w-screen max-w-sm sm:px-0 " ++
switch activeMenu {
| Some(Resources) => " opacity-100 translate-y-0 "
| _ => " hidden "
}}>
<div
className="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 overflow-hidden">
<div className="relative grid gap-6 bg-white px-5 py-6 sm:gap-6 sm:p-8">
{content.resourcesSection.entries
|> Js.Array.mapi((e: NavEntry.t, idx) =>
<Link href=e.url key={Js.Int.toString(idx)}>
<a
onClick=hideMenu
className="-m-3 p-3 block rounded-md hover:bg-gray-50 transition ease-in-out duration-150">
<div
className="h-7 w-7 float-left fill-current stroke-current text-orangedark">
{e.icon}
</div>
<dt>
<p className="ml-10 text-sm font-semibold text-gray-900">
{s(e.label)}
</p>
</dt>
<dd className="ml-10 text-sm text-gray-500"> {s(e.text)} </dd>
</a>
</Link>
)
|> React.array}
</div>
</div>
</div>
</div>
<div className="relative">
<button
onClick={toggleMenu(Community)}
type_="button"
className="text-gray-500 pl-2 group bg-white rounded-md inline-flex items-center text-base font-medium hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orangedark"
ariaExpanded=false>
<span> {s(content.communitySection.header)} </span>
<svg
className="text-gray-400 ml-2 h-5 w-5 group-hover:text-gray-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
ariaHidden=true>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
</button>
<div
className={"absolute z-10 left-1/2 transform -translate-x-1/2 mt-3 px-2 w-screen max-w-sm sm:px-0 " ++
switch activeMenu {
| Some(Community) => " opacity-100 translate-y-0 "
| _ => " hidden "
}}>
<div
className="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 overflow-hidden">
<div className="relative grid gap-6 bg-white px-5 py-6 sm:gap-6 sm:p-8">
{content.communitySection.entries
|> Js.Array.mapi((e: NavEntry.t, idx) =>
<Link href=e.url key={Js.Int.toString(idx)}>
<a
onClick=hideMenu
className="-m-3 p-3 block rounded-md hover:bg-gray-50 transition ease-in-out duration-150">
<div
className="h-7 w-7 float-left fill-current stroke-current text-orangedark">
{e.icon}
</div>
<dt>
<p className="ml-10 text-sm font-semibold text-gray-900">
{s(e.label)}
</p>
</dt>
<dd className="ml-10 text-sm text-gray-500"> {s(e.text)} </dd>
</a>
</Link>
)
|> React.array}
</div>
</div>
</div>
</div>
<FlyoutMenu name="Principles" items=content.principlesSection.entries />
<FlyoutMenu name="Resources" items=content.resourcesSection.entries />
<FlyoutMenu name="Community" items=content.communitySection.entries />
</nav>
<div className="flex-1 flex items-center justify-center px-2 md:justify-end ">
<div className="max-w-lg w-full md:max-w-xs">
Expand Down
5 changes: 1 addition & 4 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
module.exports = {
future: {
removeDeprecatedGapUtilities: true,
purgeLayersByDefault: true,
},
mode: 'jit',
purge: {
// Specify the paths to all of the template files in your project
content: [
Expand Down
6 changes: 5 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.1.tgz#9daf5745156fd84b8e9889a2dc721f0c58e894aa"
integrity sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==

"@headlessui/react@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.2.0.tgz#e48652bfce82ddf73d7f331faeb9db6526ee6874"
integrity sha512-19DkLz8gDgbi+WvkoTzi9vs0NK9TJf94vbYhMzB4LYJo03Kili0gmvXT9CiKZoxXZ7YAvy/b1U1oQKEnjWrqxw==

"@next/[email protected]":
version "10.2.0"
resolved "https://registry.yarnpkg.com/@next/env/-/env-10.2.0.tgz#154dbce2efa3ad067ebd20b7d0aa9aed775e7c97"
Expand Down Expand Up @@ -2147,7 +2152,6 @@ once@^1.3.0:

"ood@git://github.com/ocaml/ood.git#main":
version "0.0.0"
uid b37db9c51a252a7152be99c53346fd565ea7df65
resolved "git://github.com/ocaml/ood.git#b37db9c51a252a7152be99c53346fd565ea7df65"
dependencies:
bs-platform "9.0.2"
Expand Down