Skip to content

Commit

Permalink
use dialog in react component
Browse files Browse the repository at this point in the history
  • Loading branch information
elevatebart committed Dec 1, 2023
1 parent 7ffc0d4 commit 05a9269
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 79 deletions.
6 changes: 1 addition & 5 deletions components/Modal/constants/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
export const ClassBackDrop =
'fixed left-0 top-0 z-[1000010] h-screen w-screen bg-gray-900/[.80] backdrop-blur-sm'
export const ClassModalContainer =
'pointer-events-none fixed left-0 top-0 z-[1000020] h-full w-screen overflow-hidden flex items-center justify-center'
export const ClassModal =
'pointer-events-auto relative flex flex-col rounded outline outline-4 outline-gray-500/[.40] bg-white'
'pointer-events-auto fixed flex flex-col rounded outline outline-4 outline-gray-500/[.40] bg-white backdrop:bg-gray-900/[.80] backdrop:backdrop-blur-sm'
export const ClassModalStandardDimensions =
'max-h-[80vh] min-w-[200px] sm:min-w-[390px] max-w-[calc(100vw-32px)] sm:max-w-[70vw] shrink-0'
export const ClassModalFullscreenDimensions =
Expand Down
114 changes: 62 additions & 52 deletions components/Modal/react/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ import {
IconActionDelete,
} from '@cypress-design/react-icon'
import {
ClassBackDrop,
ClassCloseButton,
ClassContent,
ClassHelpLink,
ClassHelpLinkDash,
ClassModal,
ClassModalFullscreenDimensions,
ClassModalStandardDimensions,
ClassModalContainer,
ClassTitle,
ClassTitleBox,
disableBodyScroll,
Expand All @@ -38,13 +36,17 @@ export const Modal: React.FC<ModalProps> = ({
children,
fullscreen = false,
}) => {
const dialogRef = React.useRef<HTMLDialogElement>(null)

React.useEffect(() => {
if (show) {
disableBodyScroll()
dialogRef.current?.showModal()
} else {
dialogRef.current?.close()
freeBodyScroll()
}
}, [show])
}, [show, onClose])

React.useEffect(
() => () => {
Expand All @@ -53,61 +55,69 @@ export const Modal: React.FC<ModalProps> = ({
[],
)

const closeOnClickBackdrop = React.useCallback<
React.MouseEventHandler<HTMLDialogElement>
>(
(event) => {
const rect = dialogRef.current?.getBoundingClientRect()
if (!rect) return
const isInDialog =
rect.top <= event.clientY &&
event.clientY <= rect.top + rect.height &&
rect.left <= event.clientX &&
event.clientX <= rect.left + rect.width
if (!isInDialog) {
onClose?.()
}
},
[onClose],
)

return (
show &&
createPortal(
<div>
<div className={ClassBackDrop} onClick={() => onClose?.()}></div>
<dialog
ref={dialogRef}
className={clsx(
show ? ClassModal : null,
fullscreen
? ClassModalFullscreenDimensions
: ClassModalStandardDimensions,
)}
onClick={closeOnClickBackdrop}
>
<div className={ClassTitleBox}>
<div id="cy_modal_label" className={ClassTitle}>
{title}
</div>
{helpLink ? <div className={ClassHelpLinkDash} /> : null}
{helpLink ? (
<a href={helpLink} className={ClassHelpLink}>
Need help
<IconActionQuestionMarkCircle
className="ml-[4px]"
stroke-color="indigo-500"
fill-color="indigo-100"
/>
</a>
) : null}

<div
className={ClassModalContainer}
tabIndex={-1}
aria-modal="true"
aria-labelledby="cy_modal_label"
role="dialog"
>
<div
className={clsx(
ClassModal,
fullscreen
? ClassModalFullscreenDimensions
: ClassModalStandardDimensions,
)}
<div className="grow" />
<button
aria-label="Close"
className={ClassCloseButton}
onClick={() => onClose?.()}
>
<div className={ClassTitleBox}>
<div id="cy_modal_label" className={ClassTitle}>
{title}
</div>
{helpLink ? <div className={ClassHelpLinkDash} /> : null}
{helpLink ? (
<a href={helpLink} className={ClassHelpLink}>
Need help
<IconActionQuestionMarkCircle
className="ml-[4px]"
stroke-color="indigo-500"
fill-color="indigo-100"
/>
</a>
) : null}

<div className="grow" />
<button
aria-label="Close"
className={ClassCloseButton}
onClick={() => onClose?.()}
>
<IconActionDelete
className="children:transition-all"
stroke-color="gray-400"
hover-stroke-color="gray-700"
interactiveColorsOnGroup
/>
</button>
</div>
<div className={ClassContent}>{children}</div>
</div>
<IconActionDelete
className="children:transition-all"
stroke-color="gray-400"
hover-stroke-color="gray-700"
interactiveColorsOnGroup
/>
</button>
</div>
</div>,
<div className={ClassContent}>{children}</div>
</dialog>,
document.body,
)
)
Expand Down
31 changes: 14 additions & 17 deletions components/Modal/vue/Modal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,31 @@ watch(internalShow, (val) => {
onUnmounted(() => {
freeBodyScroll()
})
function closeOnClickBackdrop(event: MouseEvent) {
var rect = $dialog.value?.getBoundingClientRect()
if (!rect) return
var isInDialog =
rect.top <= event.clientY &&
event.clientY <= rect.top + rect.height &&
rect.left <= event.clientX &&
event.clientX <= rect.left + rect.width
if (!isInDialog) {
internalShow.value = false
}
}
</script>

<template>
<dialog
ref="$dialog"
:class="[
'!fixed',
internalShow ? ClassModal : null,
fullscreen
? ClassModalFullscreenDimensions
: ClassModalStandardDimensions,
]"
@click="closeOnClickBackdrop"
>
<div :class="ClassTitleBox">
<div id="cy_modal_label" :class="ClassTitle">
Expand Down Expand Up @@ -118,19 +131,3 @@ onUnmounted(() => {
</div>
</dialog>
</template>

<style lang="scss" scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
dialog::backdrop {
@apply bg-gray-900/[.80] backdrop-blur-sm;
}
</style>
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"@types/react-dom": "18",
"@typescript-eslint/eslint-plugin": "^6.13.1",
"@typescript-eslint/parser": "^6.13.1",
"@vitejs/plugin-vue": "^4.5.0",
"@vitejs/plugin-vue": "^4.5.1",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/tsconfig": "^0.4.0",
"@vueuse/integrations": "^10.6.1",
Expand Down Expand Up @@ -87,7 +87,7 @@
"react-dom": "18",
"react-live-runner": "^1.0.5",
"rimraf": "^5.0.5",
"rollup": "^4.6.0",
"rollup": "^4.6.1",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-sourcemaps": "^0.6.3",
"shiki": "^0.14.5",
Expand Down
2 changes: 1 addition & 1 deletion test/vue-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"devDependencies": {
"@cypress-design/css": "*",
"@vue/tsconfig": "^0.4.0",
"@vitejs/plugin-vue": "^4.5.0",
"@vitejs/plugin-vue": "^4.5.1",
"typescript": "^5.3.2",
"vite": "^5.0.4",
"vue-tsc": "*"
Expand Down
2 changes: 1 addition & 1 deletion test/vue-app/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const showModal = ref(false)
/><input />
</div>
<Button variant="jade-dark" @click="showModal = true">Open Modal</Button>
<Modal v-model="showModal" title="This is shown">
<Modal v-model:show="showModal" title="This is shown">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Vel reiciendis
magni quo dolor unde dolorem illum possimus laborum voluptatum maiores
blanditiis officiis fugiat sapiente, adipisci eum. Sapiente recusandae
Expand Down
Loading

0 comments on commit 05a9269

Please sign in to comment.