Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalbaljet committed Nov 20, 2024
1 parent f6ff916 commit 480367a
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 36 deletions.
7 changes: 7 additions & 0 deletions demo-app/resources/js/Pages/Local.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export default function Local() {
modalRef.current.close();
}

function alertModalId() {
alert(modalRef.current.id);
}

return (
<>
<Container>
Expand All @@ -30,6 +34,9 @@ export default function Local() {
<button onClick={closeModal}>
Close Modal through Ref
</button>
<button onClick={alertModalId}>
Alert Modal ID
</button>
</Modal>
</>
);
Expand Down
8 changes: 8 additions & 0 deletions demo-app/resources/js/Pages/Local.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ const modalRef = ref(null);
function closeModal() {
modalRef.value.close();
}
function alertModalId() {
alert(modalRef.value.id);
}
</script>

<template>
Expand All @@ -31,5 +35,9 @@ function closeModal() {
<button @click="closeModal">
Close Modal through Ref
</button>

<button @click="alertModalId">
Alert Modal ID
</button>
</Modal>
</template>
17 changes: 17 additions & 0 deletions demo-app/tests/Browser/LocalModalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,23 @@ public function it_can_open_a_local_modal_and_a_nested_one()
});
}

#[Test]
public function it_can_access_a_prop_through_a_template_ref()
{
$this->browse(function (Browser $browser) {
$browser->visit('/local')
->clickLink('Open Local Modal')
->waitForTextIn('.im-modal-content', 'This is a local modal')
->press('Alert Modal ID');

$message = $browser->driver->switchTo()->alert()->getText();

$this->assertStringStartsWith('inertiaui_modal_', $message);

$browser->dismissDialog();
});
}

#[Test]
public function it_can_close_a_local_modal_through_a_template_ref()
{
Expand Down
57 changes: 39 additions & 18 deletions react/src/HeadlessModal.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo, useState, forwardRef, useImperativeHandle, useEffect } from 'react'
import { useMemo, useState, forwardRef, useImperativeHandle, useEffect, useRef } from 'react'
import { getConfig, getConfigByType } from './config'
import { useModalIndex } from './ModalRenderer.jsx'
import { useModalStack } from './ModalRoot.jsx'
Expand All @@ -9,7 +9,6 @@ const HeadlessModal = forwardRef(({ name, children, ...props }, ref) => {
const { stack, registerLocalModal, removeLocalModal } = useModalStack()

const [localModalContext, setLocalModalContext] = useState(null)
let modalContextCopy = name ? localModalContext : stack[modalIndex]
const modalContext = useMemo(() => (name ? localModalContext : stack[modalIndex]), [name, localModalContext, modalIndex, stack])

const nextIndex = useMemo(() => {
Expand Down Expand Up @@ -39,7 +38,6 @@ const HeadlessModal = forwardRef(({ name, children, ...props }, ref) => {
registerLocalModal(name, (localContext) => {
removeListeners = localContext.registerEventListenersFromProps(props)
setLocalModalContext(localContext)
modalContextCopy = localContext
})

return () => {
Expand All @@ -52,25 +50,48 @@ const HeadlessModal = forwardRef(({ name, children, ...props }, ref) => {
return modalContext.registerEventListenersFromProps(props)
}, [name])

// Store the latest modalContext in a ref to maintain reference
const modalContextRef = useRef(modalContext)

// Update the ref whenever modalContext changes
useEffect(() => {
modalContextRef.current = modalContext
}, [modalContext])

useImperativeHandle(
ref,
() => ({
afterLeave: () => modalContextCopy.afterLeave(),
close: () => modalContextCopy.close(),
config,
emit: (...args) => modalContextCopy.emit(...args),
getChildModal: () => modalContextCopy.getChildModal(),
getParentModal: () => modalContextCopy.getParentModal(),
id: modalContextCopy?.id,
index: modalContextCopy?.index,
isOpen: modalContextCopy?.isOpen,
modalContext: modalContextCopy,
onTopOfStack: modalContextCopy?.onTopOfStack,
reload: () => modalContextCopy.reload(),
setOpen: () => modalContextCopy.setOpen(),
shouldRender: modalContextCopy?.shouldRender,
afterLeave: () => modalContextRef.current?.afterLeave(),
close: () => modalContextRef.current?.close(),
emit: (...args) => modalContextRef.current?.emit(...args),
getChildModal: () => modalContextRef.current?.getChildModal(),
getParentModal: () => modalContextRef.current?.getParentModal(),
reload: (...args) => modalContextRef.current?.reload(...args),
setOpen: () => modalContextRef.current?.setOpen(),

get id() {
return modalContextRef.current?.id
},
get index() {
return modalContextRef.current?.index
},
get isOpen() {
return modalContextRef.current?.isOpen
},
get config() {
return modalContextRef.current?.config
},
get modalContext() {
return modalContextRef.current
},
get onTopOfStack() {
return modalContextRef.current?.onTopOfStack
},
get shouldRender() {
return modalContextRef.current?.shouldRender
},
}),
[modalContextCopy],
[modalContext],
)

return (
Expand Down
35 changes: 25 additions & 10 deletions vue/src/HeadlessModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,35 @@ function emit(event, ...args) {
}
defineExpose({
emit,
afterLeave: () => modalContext.value?.afterLeave(),
close: () => modalContext.value?.close(),
config: computed(() => modalContext.value?.config),
emit,
getChildModal: () => modalContext.value?.getChildModal(),
getParentModal: () => modalContext.value?.getParentModal(),
id: computed(() => modalContext.value?.id),
index: computed(() => modalContext.value?.index),
isOpen: computed(() => modalContext.value?.isOpen),
modalContext: computed(() => modalContext.value?.modalContext),
onTopOfStack: computed(() => modalContext.value?.onTopOfStack),
reload: (...args) => modalContext.value?.reload(...args),
setOpen: (...args) => modalContext.value?.setOpen(...args),
shouldRender: computed(() => modalContext.value?.shouldRender),
getChildModal: () => modalContext.value?.getChildModal(),
getParentModal: () => modalContext.value?.getParentModal(),
get config() {
return modalContext.value?.config
},
get id() {
return modalContext.value?.id
},
get index() {
return modalContext.value?.index
},
get isOpen() {
return modalContext.value?.isOpen
},
get modalContext() {
return modalContext.value?.modalContext
},
get onTopOfStack() {
return modalContext.value?.onTopOfStack
},
get shouldRender() {
return modalContext.value?.shouldRender
},
})
const nextIndex = computed(() => {
Expand Down
31 changes: 23 additions & 8 deletions vue/src/Modal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,41 @@ import { DialogOverlay, DialogPortal, DialogRoot } from 'radix-vue'
import ModalContent from './ModalContent.vue'
import HeadlessModal from './HeadlessModal.vue'
import SlideoverContent from './SlideoverContent.vue'
import { computed, ref } from 'vue'
import { ref } from 'vue'
const modal = ref(null)
const rendered = ref(false)
defineExpose({
afterLeave: () => modal.value?.afterLeave(),
close: () => modal.value?.close(),
config: computed(() => modal.value?.config),
emit: (...args) => modal.value?.emit(...args),
getChildModal: () => modal.value?.getChildModal(),
getParentModal: () => modal.value?.getParentModal(),
id: computed(() => modal.value?.id),
index: computed(() => modal.value?.index),
isOpen: computed(() => modal.value?.isOpen),
modalContext: computed(() => modal.value?.modalContext),
onTopOfStack: computed(() => modal.value?.onTopOfStack),
reload: (...args) => modal.value?.reload(...args),
setOpen: (...args) => modal.value?.setOpen(...args),
shouldRender: computed(() => modal.value?.shouldRender),
get config() {
return modal.value?.config
},
get id() {
return modal.value?.id
},
get index() {
return modal.value?.index
},
get isOpen() {
return modal.value?.isOpen
},
get modalContext() {
return modal.value?.modalContext
},
get onTopOfStack() {
return modal.value?.onTopOfStack
},
get shouldRender() {
return modal.value?.shouldRender
},
})
</script>
Expand Down

0 comments on commit 480367a

Please sign in to comment.