Skip to content

Commit

Permalink
feat(dialog): add narrow prop
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrés Alvarez authored and Andrés Alvarez committed Nov 9, 2023
1 parent 968066e commit 598301a
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 45 deletions.
24 changes: 14 additions & 10 deletions packages/components/dialog/src/Dialog.doc.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import * as stories from './Dialog.stories'

A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.

- Supports modal and non-modal modes.
- Focus is automatically trapped when modal.
- Can be controlled or uncontrolled.
- Manages screen reader announcements with `Title` and `Description` components.
- Esc closes the component automatically.
- Supports modal and non-modal modes.
- Focus is automatically trapped when modal.
- Can be controlled or uncontrolled.
- Manages screen reader announcements with `Title` and `Description` components.
- Esc closes the component automatically.

## Install

Expand Down Expand Up @@ -89,10 +89,14 @@ import { Dialog } from '@spark-ui/dialog'

### Default

Use the various parts of `Dialog` to build a highly customizable dialog.

<Canvas of={stories.Default} />

### Controlled

Use `open` and `onOpenChange` props to control the state of the dialog. This is specially useful to close the dialog after an async operation has completed.

<Canvas of={stories.Controlled} />

### Sizes

Pick a size among `sm`, `md`, `lg` and `fullscreen`.
Expand All @@ -103,13 +107,13 @@ Pick a size among `sm`, `md`, `lg` and `fullscreen`.

### Form inside a dialog

This example shows you how to combine `Dialog` with an `HTML` form.
The `Dialog` component can be effortlessly combined with a form element.

<Canvas of={stories.HTMLForm} />
<Canvas of={stories.Form} />

### Forward focus

You can use `onOpenAutoFocus` and a `ref` to pass the focus to a specific element when the dialog opens.
Use `onOpenAutoFocus` and a `ref` to direct focus to a specific element when the dialog opens.

<Canvas of={stories.ForwardFocus} />

Expand Down
95 changes: 64 additions & 31 deletions packages/components/dialog/src/Dialog.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,50 @@ const meta: Meta<typeof Dialog> = {
export default meta

export const Default: StoryFn = () => {
const [open, setOpen] = useState(false)
return (
<Dialog>
<Dialog.Trigger asChild>
<Button>Edit profile</Button>
</Dialog.Trigger>

<Dialog.Portal>
<Dialog.Overlay />

<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Edit profile</Dialog.Title>
</Dialog.Header>

<Dialog.Body>
<Dialog.Description>
Make changes to your profile here. Click save when you are done.
</Dialog.Description>

<p>Lorem ipsum dolor sit amet</p>
</Dialog.Body>

<Dialog.Footer className="flex justify-end gap-md">
<Dialog.Close asChild>
<Button intent="neutral" design="outlined">
Cancel
</Button>
</Dialog.Close>

<Button>Submit</Button>
</Dialog.Footer>

<Dialog.CloseButton aria-label="Close edit profile" />
</Dialog.Content>
</Dialog.Portal>
</Dialog>
)
}

export const Controlled: StoryFn = () => {
const [isOpen, setIsOpen] = useState(false)

return (
<Dialog open={open} onOpenChange={setOpen}>
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<Dialog.Trigger asChild>
<Button>Edit profile</Button>
</Dialog.Trigger>
Expand Down Expand Up @@ -49,9 +89,12 @@ export const Default: StoryFn = () => {
</Dialog.Body>

<Dialog.Footer className="flex justify-end gap-md">
<Button intent="neutral" design="outlined" onClick={() => setOpen(false)}>
Cancel
</Button>
<Dialog.Close asChild>
<Button intent="neutral" design="outlined">
Cancel
</Button>
</Dialog.Close>

<Button>Submit</Button>
</Dialog.Footer>

Expand All @@ -64,25 +107,16 @@ export const Default: StoryFn = () => {

export const Sizes = () => {
const [size, setSize] = useState<ExcludeNull<DialogContentProps>['size']>('md')
const [open, setOpen] = useState(false)

const handleValueChange = (value: string) => {
setSize(value as ExcludeNull<DialogContentProps>['size'])
}

return (
<Dialog open={open} onOpenChange={setOpen}>
<Dialog>
<div className="flex gap-md">
<Dialog.Trigger asChild>
<Button onClick={() => setSize('sm')}>Small</Button>
</Dialog.Trigger>

<Dialog.Trigger asChild>
<Button onClick={() => setSize('md')}>Medium</Button>
</Dialog.Trigger>

<Dialog.Trigger asChild>
<Button onClick={() => setSize('lg')}>Large</Button>
</Dialog.Trigger>

<Dialog.Trigger asChild>
<Button onClick={() => setSize('fullscreen')}>Fullscreen</Button>
<Button>Open</Button>
</Dialog.Trigger>
</div>

Expand All @@ -97,11 +131,7 @@ export const Sizes = () => {
<Dialog.Body className="flex flex-col gap-lg">
<Dialog.Description>Please select a dialog size</Dialog.Description>

<RadioGroup
className="flex gap-md"
value={size}
onValueChange={value => setSize(value as ExcludeNull<DialogContentProps>['size'])}
>
<RadioGroup className="flex gap-md" value={size} onValueChange={handleValueChange}>
<RadioGroup.Radio value="sm">Small</RadioGroup.Radio>
<RadioGroup.Radio value="md">Medium</RadioGroup.Radio>
<RadioGroup.Radio value="lg">Large</RadioGroup.Radio>
Expand All @@ -110,10 +140,13 @@ export const Sizes = () => {
</Dialog.Body>

<Dialog.Footer className="flex justify-end gap-md">
<Button intent="neutral" design="outlined" onClick={() => setOpen(false)}>
Cancel
</Button>
<Button>Submit</Button>
<Dialog.Close asChild>
<Button intent="neutral" design="outlined">
Cancel
</Button>
</Dialog.Close>

<Button>Save</Button>
</Dialog.Footer>

<Dialog.CloseButton aria-label="Close edit size" />
Expand All @@ -123,7 +156,7 @@ export const Sizes = () => {
)
}

export const HTMLForm = () => {
export const Form = () => {
const [open, setOpen] = useState(false)
const [isAccountCreated, setIsAccountCreated] = useState(false)

Expand Down Expand Up @@ -165,7 +198,7 @@ export const HTMLForm = () => {
</Dialog.Body>

<Dialog.Footer className="flex justify-end gap-md">
{!isAccountCreated && <Button>Submit</Button>}
{!isAccountCreated && <Button type="submit">Submit</Button>}
</Dialog.Footer>
</form>

Expand Down
12 changes: 11 additions & 1 deletion packages/components/dialog/src/DialogContent.styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,31 @@ export const dialogContentStyles = cva(
md: 'max-w-sz-672',
lg: 'max-w-sz-864',
},
isNarrow: {
true: [],
false: [],
},
},
compoundVariants: [
{
size: ['sm', 'md', 'lg'],
class: [
'fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2',
'w-full max-h-[80%]',
'max-h-[80%]',
'shadow-md rounded-lg',
'data-[state=open]:animate-fade-in',
'data-[state=closed]:animate-fade-out',
],
},
{
size: ['sm', 'md', 'lg'],
isNarrow: false,
class: ['w-full'],
},
],
defaultVariants: {
size: 'md',
isNarrow: false,
},
}
)
Expand Down
12 changes: 9 additions & 3 deletions packages/components/dialog/src/DialogContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ import { forwardRef, type ReactElement, type Ref, useEffect } from 'react'
import { dialogContentStyles, type DialogContentStylesProps } from './DialogContent.styles'
import { useDialog } from './DialogContext'

export type ContentProps = RadixDialog.DialogContentProps & DialogContentStylesProps
export interface ContentProps extends RadixDialog.DialogContentProps, DialogContentStylesProps {
/**
* When set to true, the content will adjust its width to fit the content rather than taking up the full available width.
*/
isNarrow?: boolean
}

export const Content = forwardRef(
(
{ children, className, size = 'md', ...rest }: ContentProps,
{ children, className, isNarrow = false, size = 'md', ...rest }: ContentProps,
ref: Ref<HTMLDivElement>
): ReactElement => {
const { setIsFullScreen } = useDialog()
Expand All @@ -24,8 +29,9 @@ export const Content = forwardRef(
data-spark-component="dialog-content"
ref={ref}
className={dialogContentStyles({
size,
className,
isNarrow,
size,
})}
{...rest}
>
Expand Down

0 comments on commit 598301a

Please sign in to comment.