♻️(dialogs) new DialogContent component to ease up code splitting
this better permits us to have a Dialog content component somewhere else than its trigger button. Mainly did this so that the dialog title is localized with its content.
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Div, Field, Ul, H, P, Form } from '@/primitives'
|
||||
import { Field, Ul, H, P, Form, DialogContent } from '@/primitives'
|
||||
import { isRoomValid, navigateToRoom } from '@/features/rooms'
|
||||
|
||||
export const JoinMeetingDialog = () => {
|
||||
export const JoinMeetingDialogContent = () => {
|
||||
const { t } = useTranslation('home')
|
||||
return (
|
||||
<Div>
|
||||
<DialogContent title={t('joinMeeting')}>
|
||||
<Form
|
||||
onSubmit={(data) => {
|
||||
navigateToRoom((data.roomId as string).trim())
|
||||
@@ -34,6 +34,6 @@ export const JoinMeetingDialog = () => {
|
||||
</Form>
|
||||
<H lvl={2}>{t('joinMeetingTipHeading')}</H>
|
||||
<P last>{t('joinMeetingTipContent')}</P>
|
||||
</Div>
|
||||
</DialogContent>
|
||||
)
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { HStack } from '@/styled-system/jsx'
|
||||
import { authUrl, useUser } from '@/features/auth'
|
||||
import { navigateToNewRoom } from '@/features/rooms'
|
||||
import { Screen } from '@/layout/Screen'
|
||||
import { JoinMeetingDialog } from '../components/JoinMeetingDialog'
|
||||
import { JoinMeetingDialogContent } from '../components/JoinMeetingDialogContent'
|
||||
|
||||
export const Home = () => {
|
||||
const { t } = useTranslation('home')
|
||||
@@ -33,11 +33,11 @@ export const Home = () => {
|
||||
{isLoggedIn ? t('createMeeting') : t('login', { ns: 'global' })}
|
||||
</Button>
|
||||
|
||||
<Dialog title={t('joinMeeting')}>
|
||||
<Dialog>
|
||||
<Button variant="primary" outline>
|
||||
{t('joinMeeting')}
|
||||
</Button>
|
||||
<JoinMeetingDialog />
|
||||
<JoinMeetingDialogContent />
|
||||
</Dialog>
|
||||
</HStack>
|
||||
</Div>
|
||||
|
||||
@@ -5,17 +5,12 @@ import {
|
||||
Modal,
|
||||
type DialogProps as RACDialogProps,
|
||||
ModalOverlay,
|
||||
Heading,
|
||||
OverlayTriggerStateContext,
|
||||
} from 'react-aria-components'
|
||||
import { RiCloseLine } from '@remixicon/react'
|
||||
import { styled } from '@/styled-system/jsx'
|
||||
import { Box } from './Box'
|
||||
import { Div } from './Div'
|
||||
import { VerticallyOffCenter } from './VerticallyOffCenter'
|
||||
import { text } from './Text'
|
||||
import { Button } from './Button'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { styled } from '@/styled-system/jsx'
|
||||
import { Button, Box, Div, VerticallyOffCenter } from '@/primitives'
|
||||
|
||||
const StyledModalOverlay = styled(ModalOverlay, {
|
||||
base: {
|
||||
@@ -54,7 +49,6 @@ const StyledRACDialog = styled(RACDialog, {
|
||||
})
|
||||
|
||||
export type DialogProps = {
|
||||
title: string
|
||||
children: [
|
||||
trigger: ReactNode,
|
||||
dialogContent:
|
||||
@@ -64,9 +58,9 @@ export type DialogProps = {
|
||||
} & RACDialogProps
|
||||
|
||||
/**
|
||||
* a Dialog is a tuple of a trigger component (most usually a Button) that toggles some interactive content in a Dialog on top of the app
|
||||
* a Dialog is a tuple of a trigger component (most usually a Button) that toggles some interactive content in a Dialog on top of the app. You should mostly use a DialogContent as second child.
|
||||
*/
|
||||
export const Dialog = ({ title, children, ...dialogProps }: DialogProps) => {
|
||||
export const Dialog = ({ children, ...dialogProps }: DialogProps) => {
|
||||
const { t } = useTranslation()
|
||||
const isAlert = dialogProps['role'] === 'alertdialog'
|
||||
const [trigger, dialogContent] = children
|
||||
@@ -88,13 +82,6 @@ export const Dialog = ({ title, children, ...dialogProps }: DialogProps) => {
|
||||
pointerEvents="auto"
|
||||
>
|
||||
<Box size="sm" type="dialog">
|
||||
<Heading
|
||||
slot="title"
|
||||
level={1}
|
||||
className={text({ variant: 'h1' })}
|
||||
>
|
||||
{title}
|
||||
</Heading>
|
||||
{typeof dialogContent === 'function'
|
||||
? dialogContent({ close })
|
||||
: dialogContent}
|
||||
|
||||
28
src/frontend/src/primitives/DialogContent.tsx
Normal file
28
src/frontend/src/primitives/DialogContent.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import { type ReactNode } from 'react'
|
||||
import { Heading } from 'react-aria-components'
|
||||
import { text } from './Text'
|
||||
|
||||
/**
|
||||
* Dialog content Wrapper.
|
||||
*
|
||||
* Use this in a <Dialog>, next to the button triggering the dialog.
|
||||
* This is helpful to easily add the title to the dialog and keep it
|
||||
* next to the actual content code, if you happen to separate the dialog
|
||||
* trigger from the dialog content in the code.
|
||||
*/
|
||||
export const DialogContent = ({
|
||||
children,
|
||||
title,
|
||||
}: {
|
||||
title: ReactNode
|
||||
children: ReactNode
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<Heading slot="title" level={1} className={text({ variant: 'h1' })}>
|
||||
{title}
|
||||
</Heading>
|
||||
{children}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -5,6 +5,7 @@ export { Bold } from './Bold'
|
||||
export { Box } from './Box'
|
||||
export { Button } from './Button'
|
||||
export { Dialog, useCloseDialog } from './Dialog'
|
||||
export { DialogContent } from './DialogContent'
|
||||
export { Div } from './Div'
|
||||
export { Field } from './Field'
|
||||
export { Form } from './Form'
|
||||
|
||||
Reference in New Issue
Block a user