-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(modal): implement "@coveord/plasma-mantine/Modal" (#4001)
* feat(modal): wip modal * feat(modal): implement modal * feat(modal): update modal used in prompt * feat(modal): fix test * feat(modal): fix comments * feat(modal): address comments * feat(modal): remove comments
- Loading branch information
1 parent
056f015
commit 85d2568
Showing
14 changed files
with
167 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.footer { | ||
border-top: 1px solid var(--mantine-color-gray-3); | ||
} | ||
|
||
.modalFooterSticky { | ||
padding-bottom: 0; | ||
margin: var(--mb-padding) calc(-1 * var(--mb-padding)) calc(var(--mantine-spacing-md) - var(--mb-padding)) | ||
calc(-1 * var(--mb-padding)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { | ||
factory, | ||
Modal as MantineModal, | ||
ModalFactory as MantineModalFactory, | ||
ModalProps as MantineModalProps, | ||
} from '@mantine/core'; | ||
import {ModalFooter, ModalFooter as PlasmaModalFooter} from './ModalFooter'; | ||
|
||
// Need to redeclare the factory to override and add footer to the props type | ||
type PlasmaModalFactory = Omit<MantineModalFactory, 'staticComponents'> & { | ||
staticComponents: MantineModalFactory['staticComponents'] & { | ||
Footer: typeof ModalFooter; | ||
}; | ||
}; | ||
|
||
const PlasmaModal = factory<PlasmaModalFactory>((props: MantineModalProps, ref) => ( | ||
<MantineModal ref={ref} {...props} /> | ||
)); | ||
|
||
PlasmaModal.displayName = '@coveord/plasma-mantine/Modal'; | ||
PlasmaModal.Root = MantineModal.Root; | ||
PlasmaModal.Body = MantineModal.Body; | ||
PlasmaModal.Overlay = MantineModal.Overlay; | ||
PlasmaModal.Content = MantineModal.Content; | ||
PlasmaModal.Header = MantineModal.Header; | ||
PlasmaModal.Title = MantineModal.Title; | ||
PlasmaModal.CloseButton = MantineModal.CloseButton; | ||
PlasmaModal.Stack = MantineModal.Stack; | ||
PlasmaModal.Footer = PlasmaModalFooter; | ||
|
||
export const Modal = PlasmaModal; | ||
|
||
export type ModalFactory = PlasmaModalFactory; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import {useRef, useEffect} from 'react'; | ||
import clsx from 'clsx'; | ||
import {Factory, factory} from '@mantine/core'; | ||
import {StickyFooter, StickyFooterProps, StickyFooterStylesNames} from '../sticky-footer'; | ||
import classes from './Modal.module.css'; | ||
|
||
export interface ModalFooterProps extends Omit<StickyFooterProps, 'variant'> { | ||
/** | ||
* If the footer is sticky, its margin will be adjusted to counteract the padding of the Modal.Body, ensuring the footer visually sticks to the bottom of the modal. | ||
*/ | ||
sticky?: boolean; | ||
} | ||
|
||
export type ModalFooterStylesNames = StickyFooterStylesNames; | ||
|
||
export type ModalFooterFactory = Factory<{ | ||
props: ModalFooterProps; | ||
ref: HTMLDivElement; | ||
stylesNames: ModalFooterStylesNames; | ||
}>; | ||
|
||
const ensuresFooterHasEvenHeight = (footer: HTMLElement) => { | ||
const remainder = footer.offsetHeight % 2; | ||
footer.style.height = `${footer.offsetHeight - remainder + 2}px`; | ||
}; | ||
|
||
export const ModalFooter = factory<ModalFooterFactory>(({sticky, ...props}, ref) => { | ||
const _ref = useRef<HTMLDivElement>(); | ||
|
||
const footerRef = ref || _ref; | ||
|
||
useEffect(() => { | ||
if (typeof footerRef !== 'function' && footerRef.current) { | ||
ensuresFooterHasEvenHeight(footerRef.current); | ||
} | ||
|
||
// if ref === 'function', this is a callback ref. Haven't found any solution for adjusting the height in this case | ||
}, [ref, props.h]); | ||
|
||
return ( | ||
<StickyFooter | ||
className={clsx(classes.footer, {[classes.modalFooterSticky]: !!sticky})} | ||
ref={footerRef} | ||
{...props} | ||
/> | ||
); | ||
}); |
25 changes: 25 additions & 0 deletions
25
packages/mantine/src/components/modal/__tests__/Modal.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import {render, screen} from '@test-utils'; | ||
|
||
import {Modal} from '../Modal'; | ||
|
||
// Since most part of the modal component directly inherits @mantine/core, many tests are likely covered by Mantine, so we only add tests about our customizations | ||
describe('Modal', () => { | ||
it('renders footer', () => { | ||
render( | ||
<Modal opened={true} onClose={vi.fn()}> | ||
<Modal.Footer sticky>im the footer</Modal.Footer> | ||
</Modal>, | ||
); | ||
|
||
expect(screen.getByText('im the footer')).toBeInTheDocument(); | ||
}); | ||
it('renders footer in root', () => { | ||
render( | ||
<Modal.Root opened={true} onClose={vi.fn()}> | ||
<Modal.Footer>im the footer</Modal.Footer> | ||
</Modal.Root>, | ||
); | ||
|
||
expect(screen.getByText('im the footer')).toBeInTheDocument(); | ||
}); | ||
}); |
35 changes: 35 additions & 0 deletions
35
packages/mantine/src/components/modal/__tests__/ModalFooter.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import {render, screen} from '@test-utils'; | ||
|
||
import {Modal} from '../Modal'; | ||
|
||
describe('ModalFooter', () => { | ||
it('renders children', () => { | ||
render( | ||
<Modal.Footer> | ||
<div>im the children</div> | ||
</Modal.Footer>, | ||
); | ||
|
||
expect(screen.getByText('im the children')).toBeInTheDocument(); | ||
}); | ||
it('includes the .modalFooterSticky class styling if set to sticky', () => { | ||
render( | ||
<Modal.Footer sticky> | ||
<div>im the children</div> | ||
</Modal.Footer>, | ||
); | ||
|
||
const footer = screen.getByText('im the children').parentElement; | ||
expect(footer.className).contains('modalFooterSticky'); | ||
}); | ||
it('has an even height value to ensure the footer sticks completely to the bottom as a workaround to the footer positioning issue when height value is odd', () => { | ||
render( | ||
<Modal.Footer h={99}> | ||
<div>im the children</div> | ||
</Modal.Footer>, | ||
); | ||
|
||
const footer = screen.getByText('im the children').parentElement; | ||
expect(footer.offsetHeight % 2).lessThanOrEqual(Number.EPSILON); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './Modal'; | ||
export * from './ModalFooter'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters