Skip to content
Merged
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
56 changes: 23 additions & 33 deletions packages/alert-dialog/examples/basic.example.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import Component from "@reach/component-component";
import "@reach/dialog/styles.css";
import {
AlertDialog,
Expand All @@ -9,35 +8,26 @@ import {

export let name = "Basic";

export let Example = () => (
<Component
getRefs={() => ({ close: React.createRef() })}
initialState={{ showDialog: false }}
>
{({ state, setState, refs }) => (
<div>
<button onClick={() => setState({ showDialog: true })}>
Show Dialog
</button>

{state.showDialog && (
<AlertDialog leastDestructiveRef={refs.close}>
<AlertDialogLabel>Confirmation!</AlertDialogLabel>
<AlertDialogDescription>
Are you sure you want to have that milkshake?
</AlertDialogDescription>
<p>
<button>DESTROY Stuff!</button>{" "}
<button
ref={refs.close}
onClick={() => setState({ showDialog: false })}
>
Cancel
</button>
</p>
</AlertDialog>
)}
</div>
)}
</Component>
);
export let Example = () => {
const close = React.useRef(null);
const [showDialog, setShowDialog] = React.useState(false);
return (
<div>
<button onClick={() => setShowDialog(true)}>Show Dialog</button>
{showDialog && (
<AlertDialog leastDestructiveRef={close}>
<AlertDialogLabel>Confirmation!</AlertDialogLabel>
<AlertDialogDescription>
Are you sure you want to have that milkshake?
</AlertDialogDescription>
<p>
<button>DESTROY Stuff!</button>{" "}
<button ref={close} onClick={() => setShowDialog(false)}>
Cancel
</button>
</p>
</AlertDialog>
)}
</div>
);
};
3 changes: 1 addition & 2 deletions packages/alert-dialog/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@reach/alert-dialog",
"version": "0.4.0-beta.0",
"description": "Accessible React Alert Dialog.",
"author": "Ryan Florence <@ryanflorence>",
"author": "React Training <hello@reacttraining.com>",
"license": "MIT",
"main": "index.js",
"module": "es/index.js",
Expand All @@ -12,7 +12,6 @@
},
"dependencies": {
"@reach/auto-id": "^0.4.0-beta.0",
"@reach/component-component": "^0.4.0-beta.0",
"@reach/dialog": "^0.4.0-beta.0",
"@reach/utils": "^0.4.0-beta.0",
"invariant": "^2.2.4",
Expand Down
160 changes: 77 additions & 83 deletions packages/alert-dialog/src/index.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
import React, { createContext } from "react";
import Component from "@reach/component-component";
import { DialogOverlay, DialogContent } from "@reach/dialog";
import { useId } from "@reach/auto-id";
import invariant from "invariant";
import { func, bool, node, object, oneOfType } from "prop-types";

let AlertDialogContext = createContext();
let AlertDialogContext = createContext({});

let AlertDialogOverlay = React.forwardRef(
({ leastDestructiveRef, ...props }, forwardRef) => {
const labelId = useId();
const descriptionId = useId();
return (
<Component
getRefs={() => ({
labelId: `alert-dialog-${labelId}`,
descriptionId: `alert-dialog-${descriptionId}`,
leastDestructiveRef
})}
>
{({ refs }) => (
<AlertDialogContext.Provider value={refs}>
<DialogOverlay
ref={forwardRef}
data-reach-alert-dialog-overlay
initialFocusRef={leastDestructiveRef}
{...props}
/>
</AlertDialogContext.Provider>
)}
</Component>
);
}
);
export const AlertDialogOverlay = React.forwardRef(function AlertDialogOverlay(
{ leastDestructiveRef, ...props },
forwardRef
) {
const uid = useId();
const labelId = makeId("alert-dialog", uid);
const descriptionId = makeId("alert-dialog-description", uid);

return (
<AlertDialogContext.Provider
value={{
labelId,
descriptionId,
leastDestructiveRef
}}
>
<DialogOverlay
ref={forwardRef}
data-reach-alert-dialog-overlay
initialFocusRef={leastDestructiveRef}
{...props}
/>
</AlertDialogContext.Provider>
);
});

if (__DEV__) {
AlertDialogOverlay.propTypes = {
Expand All @@ -43,62 +41,61 @@ if (__DEV__) {
};
}

let AlertDialogContent = React.forwardRef(
({ children, ...props }, forwardRef) => (
<AlertDialogContext.Consumer>
{refs => (
<DialogContent
ref={forwardRef}
data-reach-alert-dialong-content
role="alertdialog"
aria-labelledby={refs.labelId}
{...props}
>
<Component
didMount={() => {
invariant(
document.getElementById(refs.labelId),
`@reach/alert-dialog: You must render a \`<AlertDialogLabel>\`
inside an \`<AlertDialog/>\`.`
);
invariant(
refs.leastDestructiveRef,
`@reach/alert-dialog: You must provide a \`leastDestructiveRef\` to
\`<AlertDialog>\` or \`<AlertDialogOverlay/>\`. Please see
https://ui.reach.tech/alert-dialog/#alertdialogoverlay-leastdestructiveref`
);
}}
children={children}
/>
</DialogContent>
)}
</AlertDialogContext.Consumer>
)
);
export const AlertDialogContent = React.forwardRef(function AlertDialogContent(
{ children, ...props },
forwardRef
) {
const { labelId, leastDestructiveRef } = React.useContext(AlertDialogContext);
React.useEffect(() => {
invariant(
document.getElementById(labelId),
`@reach/alert-dialog: You must render a \`<AlertDialogLabel>\`
inside an \`<AlertDialog/>\`.`
);
invariant(
leastDestructiveRef,
`@reach/alert-dialog: You must provide a \`leastDestructiveRef\` to
\`<AlertDialog>\` or \`<AlertDialogOverlay/>\`. Please see
https://ui.reach.tech/alert-dialog/#alertdialogoverlay-leastdestructiveref`
);
}, [labelId, leastDestructiveRef]);
return (
<DialogContent
ref={forwardRef}
data-reach-alert-dialong-content
role="alertdialog"
aria-labelledby={labelId}
{...props}
>
{children}
</DialogContent>
);
});

if (__DEV__) {
AlertDialogContent.propTypes = {
children: node
};
}

let AlertDialogLabel = props => (
<AlertDialogContext.Consumer>
{({ labelId }) => (
<div id={labelId} data-reach-alert-dialog-label {...props} />
)}
</AlertDialogContext.Consumer>
);
export const AlertDialogLabel = props => {
const { labelId } = React.useContext(AlertDialogContext);
return <div id={labelId} data-reach-alert-dialog-label {...props} />;
};

let AlertDialogDescription = props => (
<AlertDialogContext.Consumer>
{({ descriptionId }) => (
<div id={descriptionId} data-reach-alert-dialog-description {...props} />
)}
</AlertDialogContext.Consumer>
);
export const AlertDialogDescription = props => {
const { descriptionId } = React.useContext(AlertDialogContext);
return (
<div id={descriptionId} data-reach-alert-dialog-description {...props} />
);
};

let AlertDialog = ({ isOpen, onDismiss, leastDestructiveRef, ...props }) => (
export const AlertDialog = ({
isOpen,
onDismiss,
leastDestructiveRef,
...props
}) => (
<AlertDialogOverlay {...{ isOpen, onDismiss, leastDestructiveRef }}>
<AlertDialogContent {...props} />
</AlertDialogOverlay>
Expand All @@ -108,15 +105,12 @@ if (__DEV__) {
AlertDialog.propTypes = {
isOpen: bool,
onDismiss: func,
leastDestructiveRef: func,
leastDestructiveRef: oneOfType([func, object]),
children: node
};
}

export {
AlertDialog,
AlertDialogLabel,
AlertDialogDescription,
AlertDialogOverlay,
AlertDialogContent
};
// TODO: Move to @reach/utils
function makeId(id, index) {
return `${id}:${index}`;
}
Loading