From 0c4976b0bfaf6bc742bf8fb2d8acdfb9e76c6242 Mon Sep 17 00:00:00 2001 From: acd02 Date: Fri, 15 Mar 2024 11:00:44 +0100 Subject: [PATCH] feat(dialog): apply padding right to dialog title when closebutton is present Apply padding right to Dialog.Title when Dialog.CloseButton is present #1948 --- package-lock.json | 7 +++++ packages/components/dialog/package.json | 1 + .../components/dialog/src/Dialog.test.tsx | 27 +++++++++++++++++++ .../dialog/src/DialogCloseButton.tsx | 6 ++++- .../components/dialog/src/DialogContext.tsx | 27 ++++++++++++++++--- .../components/dialog/src/DialogTitle.tsx | 20 +++++++++----- 6 files changed, 77 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 461b9a271..de9190157 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2400,6 +2400,7 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", + "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -33641,6 +33642,7 @@ "@spark-ui/icon": "^2.1.2", "@spark-ui/icon-button": "^2.2.3", "@spark-ui/icons": "^1.21.6", + "@spark-ui/internal-utils": "^2.3.0", "class-variance-authority": "0.7.0" }, "peerDependencies": { @@ -33650,6 +33652,11 @@ "tailwindcss": "^3.0.0" } }, + "packages/components/dialog/node_modules/@spark-ui/internal-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@spark-ui/internal-utils/-/internal-utils-2.3.0.tgz", + "integrity": "sha512-ByvmPdwbxUJzsOmqXfL3QeAgmt3dZjXUjUdSe9r6ai0stM+cHMVgN5QsYk8cpllcoKACuP+bM7pRfaF5dMP/rA==" + }, "packages/components/divider": { "name": "@spark-ui/divider", "version": "1.0.1", diff --git a/packages/components/dialog/package.json b/packages/components/dialog/package.json index 0720b77e2..9cfae5495 100644 --- a/packages/components/dialog/package.json +++ b/packages/components/dialog/package.json @@ -47,6 +47,7 @@ "@spark-ui/icon": "^2.1.2", "@spark-ui/icon-button": "^2.2.3", "@spark-ui/icons": "^1.21.6", + "@spark-ui/internal-utils": "^2.3.0", "class-variance-authority": "0.7.0" } } diff --git a/packages/components/dialog/src/Dialog.test.tsx b/packages/components/dialog/src/Dialog.test.tsx index cf105b82c..f1d006897 100644 --- a/packages/components/dialog/src/Dialog.test.tsx +++ b/packages/components/dialog/src/Dialog.test.tsx @@ -188,4 +188,31 @@ describe('Dialog', () => { expect(screen.getByText(/dialog contents/i).parentElement).not.toHaveClass('px-xl py-lg') }) + + it('should apply padding-right to the Dialog.Title if Dialog.CloseButton is present', async () => { + render( + + + + + + Edit profile + + + +

Dialog contents

+
+ + + + + + +
+
+
+ ) + + expect(screen.getByText(/Edit profile/i)).toHaveClass('pr-3xl') + }) }) diff --git a/packages/components/dialog/src/DialogCloseButton.tsx b/packages/components/dialog/src/DialogCloseButton.tsx index 58aea3540..a20e1deb1 100644 --- a/packages/components/dialog/src/DialogCloseButton.tsx +++ b/packages/components/dialog/src/DialogCloseButton.tsx @@ -10,7 +10,7 @@ type CloseButtonElement = ElementRef export type CloseButtonProps = CloseProps & Pick -export const CloseButton = forwardRef( +const Root = forwardRef( ( { 'aria-label': ariaLabel, @@ -36,4 +36,8 @@ export const CloseButton = forwardRef( ) ) +export const CloseButton = Object.assign(Root, { + id: 'CloseButton', +}) + CloseButton.displayName = 'Dialog.CloseButton' diff --git a/packages/components/dialog/src/DialogContext.tsx b/packages/components/dialog/src/DialogContext.tsx index 4b8199bea..51fe43887 100644 --- a/packages/components/dialog/src/DialogContext.tsx +++ b/packages/components/dialog/src/DialogContext.tsx @@ -1,23 +1,44 @@ -import { createContext, type ReactNode, useContext, useState } from 'react' +import { deepFind } from '@spark-ui/internal-utils' +import { + createContext, + type ReactElement, + type ReactNode, + useContext, + useEffect, + useState, +} from 'react' export interface DialogContextState { isFullScreen: boolean setIsFullScreen: (value: boolean) => void + hasCloseButton: boolean } const DialogContext = createContext(null) -export const DialogProvider = ({ children }: { children: ReactNode }) => { +export const DialogProvider = ({ children: childrenProp }: { children: ReactNode }) => { const [isFullScreen, setIsFullScreen] = useState(false) + const [hasCloseButton, setHasCloseButton] = useState(false) + + const closeButton = deepFind(childrenProp, node => { + const reactElementId = ((node as ReactElement)?.type as { id?: string }).id + + return reactElementId === 'CloseButton' + }) + + useEffect(() => { + setHasCloseButton(!!closeButton) + }, [closeButton]) return ( - {children} + {childrenProp} ) } diff --git a/packages/components/dialog/src/DialogTitle.tsx b/packages/components/dialog/src/DialogTitle.tsx index e473be5fc..b46b19637 100644 --- a/packages/components/dialog/src/DialogTitle.tsx +++ b/packages/components/dialog/src/DialogTitle.tsx @@ -2,15 +2,21 @@ import * as RadixDialog from '@radix-ui/react-dialog' import { cx } from 'class-variance-authority' import { ElementRef, forwardRef } from 'react' +import { useDialog } from './DialogContext' + export type TitleElement = ElementRef export type TitleProps = RadixDialog.DialogTitleProps -export const Title = forwardRef(({ className, ...others }, ref) => ( - -)) +export const Title = forwardRef(({ className, ...others }, ref) => { + const { hasCloseButton } = useDialog() + + return ( + + ) +}) Title.displayName = 'Dialog.Title'