Skip to content

Commit

Permalink
docs: update for new releases
Browse files Browse the repository at this point in the history
  • Loading branch information
atomiks committed Mar 12, 2023
1 parent 02c127a commit 26e3c33
Show file tree
Hide file tree
Showing 14 changed files with 1,854 additions and 100 deletions.
20 changes: 20 additions & 0 deletions website/lib/components/Button.js
@@ -0,0 +1,20 @@
import * as React from 'react';
import {twMerge} from 'tailwind-merge';

export const Button = React.forwardRef(function Button(
props,
ref
) {
return (
<button
{...props}
ref={ref}
className={twMerge(
'cursor-default bg-gray-100/75 dark:bg-gray-800/95 rounded p-2 px-3',
'transition-colors hover:bg-gray-100/50 dark:hover:bg-gray-600',
'data-[open]:bg-gray-200/50 dark:data-[open]:bg-gray-600',
props.className
)}
/>
);
});
219 changes: 219 additions & 0 deletions website/lib/components/Dialog.js
@@ -0,0 +1,219 @@
import {
FloatingFocusManager,
FloatingOverlay,
FloatingPortal,
useClick,
useDismiss,
useFloating,
useId,
useInteractions,
useMergeRefs,
useRole,
useTransitionStyles,
} from '@floating-ui/react';
import * as React from 'react';

export function useDialog({
initialOpen = false,
open: controlledOpen,
onOpenChange: setControlledOpen,
}) {
const [uncontrolledOpen, setUncontrolledOpen] =
React.useState(initialOpen);
const [labelId, setLabelId] = React.useState();
const [descriptionId, setDescriptionId] = React.useState();

const open = controlledOpen ?? uncontrolledOpen;
const setOpen = setControlledOpen ?? setUncontrolledOpen;

const data = useFloating({
open,
onOpenChange: setOpen,
});

const context = data.context;

const click = useClick(context, {
enabled: controlledOpen == null,
});
const dismiss = useDismiss(context, {
outsidePressEvent: 'mousedown',
});
const role = useRole(context);

const interactions = useInteractions([click, dismiss, role]);

return React.useMemo(
() => ({
open,
setOpen,
...interactions,
...data,
labelId,
descriptionId,
setLabelId,
setDescriptionId,
}),
[open, setOpen, interactions, data, labelId, descriptionId]
);
}

const DialogContext = React.createContext(null);

export const useDialogContext = () => {
const context = React.useContext(DialogContext);

if (context == null) {
throw new Error(
'Dialog components must be wrapped in <Dialog />'
);
}

return context;
};

export function Dialog({children, ...options}) {
const dialog = useDialog(options);
return (
<DialogContext.Provider value={dialog}>
{children}
</DialogContext.Provider>
);
}

export const DialogTrigger = React.forwardRef(
function DialogTrigger(
{children, asChild = false, ...props},
propRef
) {
const context = useDialogContext();
const childrenRef = children.ref;
const ref = useMergeRefs([
context.refs.setReference,
propRef,
childrenRef,
]);

// `asChild` allows the user to pass any element as the anchor
if (asChild && React.isValidElement(children)) {
return React.cloneElement(
children,
context.getReferenceProps({
ref,
...props,
...children.props,
'data-state': context.open ? 'open' : 'closed',
})
);
}

return (
<button
ref={ref}
// The user can style the trigger based on the state
data-state={context.open ? 'open' : 'closed'}
{...context.getReferenceProps(props)}
>
{children}
</button>
);
}
);

export const DialogContent = React.forwardRef(
function DialogContent(props, propRef) {
const {context: floatingContext, ...context} =
useDialogContext();
const ref = useMergeRefs([
context.refs.setFloating,
propRef,
]);

const {isMounted, styles} = useTransitionStyles(
floatingContext,
{
duration: {open: 400},
}
);

return (
<FloatingPortal>
{isMounted && (
<FloatingOverlay
className="bg-gray-1000/60 backdrop-blur-sm grid place-items-center text-black"
lockScroll
>
<FloatingFocusManager context={floatingContext}>
<div
ref={ref}
aria-labelledby={context.labelId}
aria-describedby={context.descriptionId}
style={styles}
{...context.getFloatingProps(props)}
>
{props.children}
</div>
</FloatingFocusManager>
</FloatingOverlay>
)}
</FloatingPortal>
);
}
);

export const DialogHeading = React.forwardRef(
function DialogHeading({children, ...props}, ref) {
const {setLabelId} = useDialogContext();
const id = useId();

// Only sets `aria-labelledby` on the Dialog root element
// if this component is mounted inside it.
React.useLayoutEffect(() => {
setLabelId(id);
return () => setLabelId(undefined);
}, [id, setLabelId]);

return (
<h2 {...props} ref={ref} id={id}>
{children}
</h2>
);
}
);

export const DialogDescription = React.forwardRef(
function DialogDescription({children, ...props}, ref) {
const {setDescriptionId} = useDialogContext();
const id = useId();

// Only sets `aria-describedby` on the Dialog root element
// if this component is mounted inside it.
React.useLayoutEffect(() => {
setDescriptionId(id);
return () => setDescriptionId(undefined);
}, [id, setDescriptionId]);

return (
<p {...props} ref={ref} id={id}>
{children}
</p>
);
}
);

export const DialogClose = React.forwardRef(function DialogClose(
{children, ...props},
ref
) {
const {setOpen} = useDialogContext();
return (
<button
type="button"
{...props}
ref={ref}
onClick={() => setOpen(false)}
>
{children}
</button>
);
});
7 changes: 7 additions & 0 deletions website/lib/components/Layout.js

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

4 changes: 2 additions & 2 deletions website/lib/components/Logos.js
Expand Up @@ -8,14 +8,14 @@ import {

export function Logos({items}) {
return (
<div className="gap-8 flex flex-wrap justify-center my-10 invert dark:invert-0">
<div className="flex flex-wrap justify-center my-10 invert dark:invert-0">
<FloatingDelayGroup delay={{open: 1000, close: 200}}>
{items.map((item) => (
<Tooltip key={item.label} content={item.label}>
<TooltipTrigger asChild>
<a
href={item.url}
className="opacity-70 dark:opacity-30 hover:opacity-100 transition-opacity"
className="opacity-70 dark:opacity-30 hover:opacity-100 transition-opacity px-4"
rel="noopener noreferrer"
>
<img
Expand Down

0 comments on commit 26e3c33

Please sign in to comment.