Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(components): add dialog component #68

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
5 changes: 5 additions & 0 deletions apps/docs/src/config/sidebarConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ export const sidebarConfig: DocsConfig = {
label: "Checkbox Group",
href: "/components/checkbox-group",
},
{
label: "Dialog",
href: "/components/dialog",
new: true,
},
{
label: "Dropdown Menu",
href: "/components/dropdown-menu",
Expand Down
115 changes: 115 additions & 0 deletions apps/docs/src/content/components/dialog.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
title: Dialog
description: A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
links:
source: https://github.com/lmsqueezy/wedges/blob/main/packages/wedges/src/components/Dialog/Dialog.tsx
radix: https://www.radix-ui.com/docs/primitives/components/dialog
---


<PreviewComponent name="dialog/preview" />

### Usage

```tsx
import { Dialog } from "@lemonsqueezy/wedges";
```

```tsx showLineNumbers
<Dialog
open={open}
title="Dialog Title"
description="Dialog Description"
>
Dialog content goes here.
</Dialog>
```

For more advanced usage, you can use the Dialog.Root component to compose your own Dialog. These components include pre-defined styles and accessiblity features.

```tsx showLineNumbers
<Dialog.Root>
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
</Dialog.Header>

Dialog content goes here.

<Dialog.Footer>
Dialog footer goes here.
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>
```

### API Reference

#### Dialog
The Wedges component of the Dialog. In most cases this is the only Dialog component you will need to use.

<PropsTable
content={[
[{ value: "open" }, { value: "boolean" }, { value: "false" }],
[{ value: "defaultOpen" }, { value: "boolean" }, { value: "false" }],
[{ value: "onOpenChange" }, { value: "(open: boolean) => void" }, {}],
[{ value: "title" }, { value: "ReactNode" }, {}],
[{ value: "description" }, { value: "ReactNode" }, {}],
[{ value: "size" }, { value: '"sm" | "md" | "lg" | "xl"' }, { value: '"md"' }],
[{ value: "container" }, { value: "HTMLElement" }, { value: "document.body" }],
]}
/>

#### Dialog.Content

Extends the <a href="https://www.radix-ui.com/primitives/docs/components/dialog#content" target="_blank" rel='nofollow noreferrer'>Radix Dialog Content</a> primitive with custom configuration.

<PropsTable
content={[
[{ value: "size" }, { value: '"sm" | "md" | "lg" | "xl"' }, { value: '"md"' }],
]}
/>

#### Dialog.Header

<PropsTable
content={[
[{ value: "title" }, { value: "ReactNode" }, {}],
[{ value: "description" }, { value: "ReactNode" }, {}],
]}
/>

#### Dialog.Root

Extends the <a href="https://www.radix-ui.com/primitives/docs/components/dialog#root" target="_blank" rel='nofollow noreferrer'>Radix Dialog Root</a> primitive.

#### Dialog.Overlay

Extends the <a href="https://www.radix-ui.com/primitives/docs/components/dialog#overlay" target="_blank" rel='nofollow noreferrer'>Radix Dialog Overlay</a> primitive.

#### Dialog.Title

Extends the <a href="https://www.radix-ui.com/primitives/docs/components/dialog#title" target="_blank" rel='nofollow noreferrer'>Radix Dialog Title</a> primitive.

#### Dialog.Description

Extends the <a href="https://www.radix-ui.com/primitives/docs/components/dialog#description" target="_blank" rel='nofollow noreferrer'>Radix Dialog Description</a> primitive.

#### Dialog.Trigger

Extends the <a href="https://www.radix-ui.com/primitives/docs/components/dialog#trigger" target="_blank" rel='nofollow noreferrer'>Radix Dialog Trigger</a> primitive.

#### Dialog.Footer

Extends the <a href="https://www.radix-ui.com/primitives/docs/components/dialog#footer" target="_blank" rel='nofollow noreferrer'>Radix Dialog Footer</a> primitive.

#### Dialog.Close

Extends the <a href="https://www.radix-ui.com/primitives/docs/components/dialog#close" target="_blank" rel='nofollow noreferrer'>Radix Dialog Close</a> primitive.

### Examples

<PreviewComponent name="dialog/example-1" />
<PreviewComponent name="dialog/example-2" />
30 changes: 30 additions & 0 deletions apps/docs/src/examples/dialog/example-1.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useRef } from "react";
import { Button, Dialog } from "@lemonsqueezy/wedges";

export default function Example() {
// You most likely don't need to use `containerRef` in your implementation. This is just for preview.
const containerRef = useRef<HTMLDivElement>(null);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mounting the dialog into a container rather than the document.body so we can apply the dark and light themes during previews.


return (
<div ref={containerRef}>
<Dialog.Root>
<Dialog.Trigger asChild>
<Button>Open Dialog</Button>
</Dialog.Trigger>

<Dialog.Content className="text-left" container={containerRef.current}>
<Dialog.Header>
<Dialog.Title>Dialog Custom Close</Dialog.Title>
<Dialog.Description>Dialog with custom close button</Dialog.Description>
</Dialog.Header>
Dialog content goes here.
<Dialog.Footer>
<Dialog.Close asChild>
<Button variant="tertiary">Close</Button>
</Dialog.Close>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>
</div>
);
}
30 changes: 30 additions & 0 deletions apps/docs/src/examples/dialog/example-2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useRef, useState } from "react";
import { Button, Dialog } from "@lemonsqueezy/wedges";

export default function Example() {
// You most likely don't need to use `containerRef` in your implementation. This is just for preview.
const containerRef = useRef<HTMLDivElement>(null);
const [open, setOpen] = useState(false);

return (
<div ref={containerRef}>
<Button onClick={() => setOpen(true)}>Open Dialog</Button>

<Dialog
open={open}
onOpenChange={setOpen}
container={containerRef.current}
className="text-left"
title="Dialog With Footer"
description="Dialog description"
>
Dialog content goes here.
<Dialog.Footer>
<Button variant="tertiary" onClick={() => setOpen(false)}>
Close
</Button>
</Dialog.Footer>
</Dialog>
</div>
);
}
25 changes: 25 additions & 0 deletions apps/docs/src/examples/dialog/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useRef, useState } from "react";
import { Button, Dialog } from "@lemonsqueezy/wedges";

export default function Example() {
// You most likely don't need to use `containerRef` in your implementation. This is just for preview.
const containerRef = useRef<HTMLDivElement>(null);
const [open, setOpen] = useState(false);

return (
<div ref={containerRef}>
<Button onClick={() => setOpen(true)}>Open Dialog</Button>

<Dialog
open={open}
onOpenChange={setOpen}
container={containerRef.current}
className="text-left"
title="Dialog Title"
description="Dialog description"
>
Dialog content goes here.
</Dialog>
</div>
);
}
97 changes: 97 additions & 0 deletions apps/docs/src/examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,103 @@ export function Example() {
</div>
);
}
`,
},
"dialog/example-1": {
component: lazy(() => import("@/examples/dialog/example-1.tsx")),
code: `import { useRef } from "react";
import { Button, Dialog } from "@lemonsqueezy/wedges";

export function Example() {
// You most likely don't need to use \`containerRef\` in your implementation. This is just for preview.
const containerRef = useRef<HTMLDivElement>(null);

return (
<div ref={containerRef}>
<Dialog.Root>
<Dialog.Trigger asChild>
<Button>Open Dialog</Button>
</Dialog.Trigger>

<Dialog.Content className="text-left" container={containerRef.current}>
<Dialog.Header>
<Dialog.Title>Dialog Custom Close</Dialog.Title>
<Dialog.Description>Dialog with custom close button</Dialog.Description>
</Dialog.Header>
Dialog content goes here.
<Dialog.Footer>
<Dialog.Close asChild>
<Button variant="tertiary">Close</Button>
</Dialog.Close>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>
</div>
);
}
`,
},
"dialog/example-2": {
component: lazy(() => import("@/examples/dialog/example-2.tsx")),
code: `import { useRef, useState } from "react";
import { Button, Dialog } from "@lemonsqueezy/wedges";

export function Example() {
// You most likely don't need to use \`containerRef\` in your implementation. This is just for preview.
const containerRef = useRef<HTMLDivElement>(null);
const [open, setOpen] = useState(false);

return (
<div ref={containerRef}>
<Button onClick={() => setOpen(true)}>Open Dialog</Button>

<Dialog
open={open}
onOpenChange={setOpen}
container={containerRef.current}
className="text-left"
title="Dialog With Footer"
description="Dialog description"
>
Dialog content goes here.
<Dialog.Footer>
<Button variant="tertiary" onClick={() => setOpen(false)}>
Close
</Button>
</Dialog.Footer>
</Dialog>
</div>
);
}
`,
},
"dialog/preview": {
component: lazy(() => import("@/examples/dialog/preview.tsx")),
code: `import { useRef, useState } from "react";
import { Button, Dialog } from "@lemonsqueezy/wedges";

export function Example() {
// You most likely don't need to use \`containerRef\` in your implementation. This is just for preview.
const containerRef = useRef<HTMLDivElement>(null);
const [open, setOpen] = useState(false);

return (
<div ref={containerRef}>
<Button onClick={() => setOpen(true)}>Open Dialog</Button>

<Dialog
open={open}
onOpenChange={setOpen}
container={containerRef.current}
className="text-left"
title="Dialog Title"
description="Dialog description"
>
Dialog content goes here.
</Dialog>
</div>
);
}
`,
},
"dropdown-menu/example-1": {
Expand Down
1 change: 1 addition & 0 deletions packages/wedges/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"@iconicicons/react": "latest",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.0.7",
Expand Down
Loading
Loading