refactor: migrate createEventDispatcher to Svelte 5 callback props
Migrate 5 components from Svelte 4 createEventDispatcher to Svelte 5 callback props:
- DropdownMenu.svelte (removed unused dispatcher)
- ProjectListItem.svelte (edit, togglePublish, delete events)
- PostListItem.svelte (edit, togglePublish, delete events)
- AlbumListItem.svelte (toggleDropdown, edit, togglePublish, delete events)
- InlineComposerModal.svelte (close, saved events + migrate export let to $props)
Updated parent components to use onevent={handler} syntax instead of on:event={handler}.
This commit is contained in:
parent
d964bf05cd
commit
4337b57dee
8 changed files with 58 additions and 57 deletions
|
|
@ -1,6 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation'
|
import { goto } from '$app/navigation'
|
||||||
import { createEventDispatcher } from 'svelte'
|
|
||||||
import AdminByline from './AdminByline.svelte'
|
import AdminByline from './AdminByline.svelte'
|
||||||
|
|
||||||
interface Photo {
|
interface Photo {
|
||||||
|
|
@ -33,16 +32,13 @@
|
||||||
interface Props {
|
interface Props {
|
||||||
album: Album
|
album: Album
|
||||||
isDropdownActive?: boolean
|
isDropdownActive?: boolean
|
||||||
|
ontoggledropdown?: (event: CustomEvent<{ albumId: number; event: MouseEvent }>) => void
|
||||||
|
onedit?: (event: CustomEvent<{ album: Album; event: MouseEvent }>) => void
|
||||||
|
ontogglepublish?: (event: CustomEvent<{ album: Album; event: MouseEvent }>) => void
|
||||||
|
ondelete?: (event: CustomEvent<{ album: Album; event: MouseEvent }>) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
let { album, isDropdownActive = false }: Props = $props()
|
let { album, isDropdownActive = false, ontoggledropdown, onedit, ontogglepublish, ondelete }: Props = $props()
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<{
|
|
||||||
toggleDropdown: { albumId: number; event: MouseEvent }
|
|
||||||
edit: { album: Album; event: MouseEvent }
|
|
||||||
togglePublish: { album: Album; event: MouseEvent }
|
|
||||||
delete: { album: Album; event: MouseEvent }
|
|
||||||
}>()
|
|
||||||
|
|
||||||
function formatRelativeTime(dateString: string): string {
|
function formatRelativeTime(dateString: string): string {
|
||||||
const date = new Date(dateString)
|
const date = new Date(dateString)
|
||||||
|
|
@ -72,19 +68,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleToggleDropdown(event: MouseEvent) {
|
function handleToggleDropdown(event: MouseEvent) {
|
||||||
dispatch('toggleDropdown', { albumId: album.id, event })
|
ontoggledropdown?.(new CustomEvent('toggledropdown', { detail: { albumId: album.id, event } }))
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEdit(event: MouseEvent) {
|
function handleEdit(event: MouseEvent) {
|
||||||
dispatch('edit', { album, event })
|
onedit?.(new CustomEvent('edit', { detail: { album, event } }))
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTogglePublish(event: MouseEvent) {
|
function handleTogglePublish(event: MouseEvent) {
|
||||||
dispatch('togglePublish', { album, event })
|
ontogglepublish?.(new CustomEvent('togglepublish', { detail: { album, event } }))
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDelete(event: MouseEvent) {
|
function handleDelete(event: MouseEvent) {
|
||||||
dispatch('delete', { album, event })
|
ondelete?.(new CustomEvent('delete', { detail: { album, event } }))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get thumbnail - try cover photo first, then first photo
|
// Get thumbnail - try cover photo first, then first photo
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { browser } from '$app/environment'
|
import { browser } from '$app/environment'
|
||||||
import { computePosition, flip, shift, offset, autoUpdate } from '@floating-ui/dom'
|
import { computePosition, flip, shift, offset, autoUpdate } from '@floating-ui/dom'
|
||||||
import ChevronRight from '$icons/chevron-right.svg?component'
|
import ChevronRight from '$icons/chevron-right.svg?component'
|
||||||
|
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
let dropdownElement: HTMLDivElement
|
let dropdownElement: HTMLDivElement
|
||||||
let cleanup: (() => void) | null = null
|
let cleanup: (() => void) | null = null
|
||||||
const dispatch = createEventDispatcher()
|
|
||||||
|
|
||||||
// Track which submenu is open
|
// Track which submenu is open
|
||||||
let openSubmenuId = $state<string | null>(null)
|
let openSubmenuId = $state<string | null>(null)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte'
|
|
||||||
import { goto } from '$app/navigation'
|
import { goto } from '$app/navigation'
|
||||||
import Modal from './Modal.svelte'
|
import Modal from './Modal.svelte'
|
||||||
import Composer from './composer'
|
import Composer from './composer'
|
||||||
|
|
@ -13,11 +12,25 @@
|
||||||
import type { JSONContent } from '@tiptap/core'
|
import type { JSONContent } from '@tiptap/core'
|
||||||
import type { Media } from '@prisma/client'
|
import type { Media } from '@prisma/client'
|
||||||
|
|
||||||
export let isOpen = false
|
interface Props {
|
||||||
export let initialMode: 'modal' | 'page' = 'modal'
|
isOpen?: boolean
|
||||||
export let initialPostType: 'post' | 'essay' = 'post'
|
initialMode?: 'modal' | 'page'
|
||||||
export let initialContent: JSONContent | undefined = undefined
|
initialPostType?: 'post' | 'essay'
|
||||||
export let closeOnSave = true
|
initialContent?: JSONContent
|
||||||
|
closeOnSave?: boolean
|
||||||
|
onclose?: (event: CustomEvent) => void
|
||||||
|
onsaved?: (event: CustomEvent) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
let {
|
||||||
|
isOpen = $bindable(false),
|
||||||
|
initialMode = 'modal',
|
||||||
|
initialPostType = 'post',
|
||||||
|
initialContent = undefined,
|
||||||
|
closeOnSave = true,
|
||||||
|
onclose,
|
||||||
|
onsaved
|
||||||
|
}: Props = $props()
|
||||||
|
|
||||||
type PostType = 'post' | 'essay'
|
type PostType = 'post' | 'essay'
|
||||||
type ComposerMode = 'modal' | 'page'
|
type ComposerMode = 'modal' | 'page'
|
||||||
|
|
@ -48,7 +61,6 @@
|
||||||
let isMediaDetailsOpen = false
|
let isMediaDetailsOpen = false
|
||||||
|
|
||||||
const CHARACTER_LIMIT = 600
|
const CHARACTER_LIMIT = 600
|
||||||
const dispatch = createEventDispatcher()
|
|
||||||
|
|
||||||
function handleClose() {
|
function handleClose() {
|
||||||
if (hasContent() && !confirm('Are you sure you want to close? Your changes will be lost.')) {
|
if (hasContent() && !confirm('Are you sure you want to close? Your changes will be lost.')) {
|
||||||
|
|
@ -56,7 +68,7 @@
|
||||||
}
|
}
|
||||||
resetComposer()
|
resetComposer()
|
||||||
isOpen = false
|
isOpen = false
|
||||||
dispatch('close')
|
onclose?.(new CustomEvent('close'))
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasContent(): boolean {
|
function hasContent(): boolean {
|
||||||
|
|
@ -207,7 +219,7 @@
|
||||||
if (closeOnSave) {
|
if (closeOnSave) {
|
||||||
isOpen = false
|
isOpen = false
|
||||||
}
|
}
|
||||||
dispatch('saved')
|
onsaved?.(new CustomEvent('saved'))
|
||||||
if (postType === 'essay') {
|
if (postType === 'essay') {
|
||||||
goto('/admin/posts')
|
goto('/admin/posts')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,17 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation'
|
import { goto } from '$app/navigation'
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import AdminByline from './AdminByline.svelte'
|
import AdminByline from './AdminByline.svelte'
|
||||||
import type { AdminPost } from '$lib/types/admin'
|
import type { AdminPost } from '$lib/types/admin'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
post: AdminPost
|
post: AdminPost
|
||||||
|
onedit?: (event: CustomEvent<{ post: AdminPost }>) => void
|
||||||
|
ontogglepublish?: (event: CustomEvent<{ post: AdminPost }>) => void
|
||||||
|
ondelete?: (event: CustomEvent<{ post: AdminPost }>) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
let { post }: Props = $props()
|
let { post, onedit, ontogglepublish, ondelete }: Props = $props()
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<{
|
|
||||||
edit: { post: AdminPost }
|
|
||||||
togglePublish: { post: AdminPost }
|
|
||||||
delete: { post: AdminPost }
|
|
||||||
}>()
|
|
||||||
|
|
||||||
let isDropdownOpen = $state(false)
|
let isDropdownOpen = $state(false)
|
||||||
|
|
||||||
|
|
@ -38,19 +35,19 @@
|
||||||
|
|
||||||
function handleEdit(event: MouseEvent) {
|
function handleEdit(event: MouseEvent) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
dispatch('edit', { post })
|
onedit?.(new CustomEvent('edit', { detail: { post } }))
|
||||||
goto(`/admin/posts/${post.id}/edit`)
|
goto(`/admin/posts/${post.id}/edit`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTogglePublish(event: MouseEvent) {
|
function handleTogglePublish(event: MouseEvent) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
dispatch('togglePublish', { post })
|
ontogglepublish?.(new CustomEvent('togglepublish', { detail: { post } }))
|
||||||
isDropdownOpen = false
|
isDropdownOpen = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDelete(event: MouseEvent) {
|
function handleDelete(event: MouseEvent) {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
dispatch('delete', { post })
|
ondelete?.(new CustomEvent('delete', { detail: { post } }))
|
||||||
isDropdownOpen = false
|
isDropdownOpen = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation'
|
import { goto } from '$app/navigation'
|
||||||
import { createEventDispatcher, onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import AdminByline from './AdminByline.svelte'
|
import AdminByline from './AdminByline.svelte'
|
||||||
import { clickOutside } from '$lib/actions/clickOutside'
|
import { clickOutside } from '$lib/actions/clickOutside'
|
||||||
|
|
||||||
|
|
@ -8,15 +8,12 @@
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
project: AdminProject
|
project: AdminProject
|
||||||
|
onedit?: (event: CustomEvent<{ project: AdminProject }>) => void
|
||||||
|
ontogglepublish?: (event: CustomEvent<{ project: AdminProject }>) => void
|
||||||
|
ondelete?: (event: CustomEvent<{ project: AdminProject }>) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
let { project }: Props = $props()
|
let { project, onedit, ontogglepublish, ondelete }: Props = $props()
|
||||||
|
|
||||||
const dispatch = createEventDispatcher<{
|
|
||||||
edit: { project: AdminProject }
|
|
||||||
togglePublish: { project: AdminProject }
|
|
||||||
delete: { project: AdminProject }
|
|
||||||
}>()
|
|
||||||
|
|
||||||
let isDropdownOpen = $state(false)
|
let isDropdownOpen = $state(false)
|
||||||
|
|
||||||
|
|
@ -57,15 +54,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEdit() {
|
function handleEdit() {
|
||||||
dispatch('edit', { project })
|
onedit?.(new CustomEvent('edit', { detail: { project } }))
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTogglePublish() {
|
function handleTogglePublish() {
|
||||||
dispatch('togglePublish', { project })
|
ontogglepublish?.(new CustomEvent('togglepublish', { detail: { project } }))
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDelete() {
|
function handleDelete() {
|
||||||
dispatch('delete', { project })
|
ondelete?.(new CustomEvent('delete', { detail: { project } }))
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleClickOutside() {
|
function handleClickOutside() {
|
||||||
|
|
|
||||||
|
|
@ -323,10 +323,10 @@
|
||||||
<AlbumListItem
|
<AlbumListItem
|
||||||
{album}
|
{album}
|
||||||
isDropdownActive={activeDropdown === album.id}
|
isDropdownActive={activeDropdown === album.id}
|
||||||
on:toggleDropdown={handleToggleDropdown}
|
ontoggledropdown={handleToggleDropdown}
|
||||||
on:edit={handleEdit}
|
onedit={handleEdit}
|
||||||
on:togglePublish={handleTogglePublish}
|
ontogglepublish={handleTogglePublish}
|
||||||
on:delete={handleDelete}
|
ondelete={handleDelete}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ const statusFilterOptions = [
|
||||||
initialMode="page"
|
initialMode="page"
|
||||||
initialPostType="post"
|
initialPostType="post"
|
||||||
closeOnSave={false}
|
closeOnSave={false}
|
||||||
on:saved={handleComposerSaved}
|
onsaved={handleComposerSaved}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
@ -186,9 +186,9 @@ const statusFilterOptions = [
|
||||||
{#each filters.items as post (post.id)}
|
{#each filters.items as post (post.id)}
|
||||||
<PostListItem
|
<PostListItem
|
||||||
{post}
|
{post}
|
||||||
on:edit={handleEdit}
|
onedit={handleEdit}
|
||||||
on:togglePublish={handleTogglePublish}
|
ontogglepublish={handleTogglePublish}
|
||||||
on:delete={handleDelete}
|
ondelete={handleDelete}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -168,9 +168,9 @@
|
||||||
{#each filters.items as project (project.id)}
|
{#each filters.items as project (project.id)}
|
||||||
<ProjectListItem
|
<ProjectListItem
|
||||||
{project}
|
{project}
|
||||||
on:edit={handleEdit}
|
onedit={handleEdit}
|
||||||
on:togglePublish={handleTogglePublish}
|
ontogglepublish={handleTogglePublish}
|
||||||
on:delete={handleDelete}
|
ondelete={handleDelete}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue