refactor: remove EnhancedComposer backward compatibility

- Remove EnhancedComposer shim and old backup file
- Update all imports to use new Composer from ./composer
- Fix editor command implementations for link operations
- Fix dropdown hook usage with proper reactive patterns
- All 5 components now directly import the modular implementation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Justin Edmund 2025-06-26 09:12:08 -04:00
parent 237d8f8c89
commit e64788962e
10 changed files with 47 additions and 1418 deletions

View file

@ -8,7 +8,7 @@
import StatusDropdown from './StatusDropdown.svelte'
import UnifiedMediaModal from './UnifiedMediaModal.svelte'
import SmartImage from '../SmartImage.svelte'
import EnhancedComposer from './EnhancedComposer.svelte'
import Composer from './composer'
import { authenticatedFetch } from '$lib/admin-auth'
import { toast } from '$lib/stores/toast'
import type { Album } from '@prisma/client'
@ -350,7 +350,7 @@
<!-- Content Panel -->
<div class="panel panel-content" class:active={activeTab === 'content'}>
<EnhancedComposer
<Composer
bind:this={editorInstance}
bind:data={formData.content}
placeholder="Add album content..."

File diff suppressed because it is too large Load diff

View file

@ -1,41 +0,0 @@
<!--
This file is a shim for backward compatibility.
The actual implementation is in ./composer/ComposerCore.svelte
-->
<script lang="ts">
import ComposerCore from './composer/ComposerCore.svelte'
import type { ComposerProps } from './composer/types'
// Re-export all props
let props: ComposerProps = $props()
// Re-export component reference
let composerRef = $state<ComposerCore>()
// Re-export public methods
export function focus() {
composerRef?.focus()
}
export function blur() {
composerRef?.blur()
}
export function clear() {
composerRef?.clear()
}
export function isEmpty() {
return composerRef?.isEmpty() || true
}
export function getContent() {
return composerRef?.getContent()
}
export function getText() {
return composerRef?.getText() || ''
}
</script>
<ComposerCore bind:this={composerRef} {...props} />

View file

@ -2,7 +2,7 @@
import { createEventDispatcher } from 'svelte'
import { goto } from '$app/navigation'
import Modal from './Modal.svelte'
import EnhancedComposer from './EnhancedComposer.svelte'
import Composer from './composer'
import AdminSegmentedControl from './AdminSegmentedControl.svelte'
import FormField from './FormField.svelte'
import Button from './Button.svelte'
@ -270,7 +270,7 @@
</div>
<div class="composer-body">
<EnhancedComposer
<Composer
bind:this={editorInstance}
bind:data={content}
onChange={(newContent) => {
@ -423,7 +423,7 @@
</div>
{:else}
<div class="content-section">
<EnhancedComposer
<Composer
bind:this={editorInstance}
bind:data={content}
onChange={(newContent) => {
@ -471,7 +471,7 @@
</Button>
{/if}
<div class="composer-body">
<EnhancedComposer
<Composer
bind:this={editorInstance}
bind:data={content}
onChange={(newContent) => {

View file

@ -4,7 +4,7 @@
import AdminPage from './AdminPage.svelte'
import AdminSegmentedControl from './AdminSegmentedControl.svelte'
import FormField from './FormField.svelte'
import EnhancedComposer from './EnhancedComposer.svelte'
import Composer from './composer'
import ProjectMetadataForm from './ProjectMetadataForm.svelte'
import ProjectBrandingForm from './ProjectBrandingForm.svelte'
import ProjectImagesForm from './ProjectImagesForm.svelte'
@ -274,7 +274,7 @@
<!-- Case Study Panel -->
<div class="panel panel-case-study" class:active={activeTab === 'case-study'}>
<EnhancedComposer
<Composer
bind:this={editorRef}
bind:data={formData.caseStudyContent}
onChange={handleEditorChange}

View file

@ -92,19 +92,23 @@
let showMediaDropdown = $state(false)
// Text style dropdown
const textStyleDropdown = useDropdown({
triggerRef: toolbarRef?.getDropdownRefs().textStyle,
isOpen: showTextStyleDropdown,
onClose: () => (showTextStyleDropdown = false),
portalClass: 'dropdown-menu-portal'
const textStyleDropdown = $derived.by(() => {
return useDropdown({
triggerRef: toolbarRef?.getDropdownRefs()?.textStyle,
isOpen: showTextStyleDropdown,
onClose: () => (showTextStyleDropdown = false),
portalClass: 'dropdown-menu-portal'
})
})
// Media dropdown
const mediaDropdown = useDropdown({
triggerRef: toolbarRef?.getDropdownRefs().media,
isOpen: showMediaDropdown,
onClose: () => (showMediaDropdown = false),
portalClass: 'media-dropdown-portal'
const mediaDropdown = $derived.by(() => {
return useDropdown({
triggerRef: toolbarRef?.getDropdownRefs()?.media,
isOpen: showMediaDropdown,
onClose: () => (showMediaDropdown = false),
portalClass: 'media-dropdown-portal'
})
})
// Event handlers
@ -242,11 +246,11 @@
showMediaLibrary={!!features.mediaLibrary}
onTextStyleDropdownToggle={() => {
showTextStyleDropdown = !showTextStyleDropdown
textStyleDropdown.toggle()
textStyleDropdown?.toggle()
}}
onMediaDropdownToggle={() => {
showMediaDropdown = !showMediaDropdown
mediaDropdown.toggle()
mediaDropdown?.toggle()
}}
/>
{/if}
@ -286,7 +290,7 @@
{#if showTextStyleDropdown && editor}
<TextStyleDropdown
{editor}
position={textStyleDropdown.position()}
position={textStyleDropdown?.position() || { top: 0, left: 0 }}
{features}
onDismiss={() => (showTextStyleDropdown = false)}
/>
@ -296,7 +300,7 @@
{#if showMediaDropdown && editor && features.mediaLibrary}
<MediaInsertDropdown
{editor}
position={mediaDropdown.position()}
position={mediaDropdown?.position() || { top: 0, left: 0 }}
{features}
{albumId}
onDismiss={() => (showMediaDropdown = false)}

View file

@ -76,7 +76,18 @@
function handleSaveLink(newUrl: string) {
if (!editor || linkEditPos === null) return
editor.commands.updateLinkUrl(linkEditPos, newUrl)
// Update link by setting selection and re-applying link mark
const { state } = editor
const { doc } = state
const node = doc.nodeAt(linkEditPos)
if (node) {
editor
.chain()
.focus()
.setTextSelection({ from: linkEditPos, to: linkEditPos + node.nodeSize })
.setLink({ href: newUrl })
.run()
}
showLinkEditDialog = false
linkEditPos = null
linkEditUrl = ''
@ -92,7 +103,8 @@
function handleRemoveLink() {
if (!editor || linkContextPos === null) return
editor.commands.removeLink(linkContextPos)
// Remove link by unset link command
editor.chain().focus().unsetLink().run()
showLinkContextMenu = false
linkContextPos = null
linkContextUrl = null

View file

@ -1,5 +1,6 @@
// Export ComposerCore as EnhancedComposer for backward compatibility
export { default as EnhancedComposer } from './ComposerCore.svelte'
// Export the main composer component
export { default } from './ComposerCore.svelte'
export { default as Composer } from './ComposerCore.svelte'
// Export types
export type { ComposerVariant, ComposerFeatures, ComposerProps } from './types'

View file

@ -3,7 +3,7 @@
import { goto } from '$app/navigation'
import { onMount } from 'svelte'
import AdminPage from '$lib/components/admin/AdminPage.svelte'
import EnhancedComposer from '$lib/components/admin/EnhancedComposer.svelte'
import Composer from '$lib/components/admin/composer'
import LoadingSpinner from '$lib/components/admin/LoadingSpinner.svelte'
import PostMetadataPopover from '$lib/components/admin/PostMetadataPopover.svelte'
import DeleteConfirmationModal from '$lib/components/admin/DeleteConfirmationModal.svelte'
@ -396,7 +396,7 @@
{#if config?.showContent && contentReady}
<div class="editor-wrapper">
<EnhancedComposer bind:data={content} placeholder="Continue writing..." />
<Composer bind:data={content} placeholder="Continue writing..." />
</div>
{/if}
</div>

View file

@ -3,7 +3,7 @@
import { goto } from '$app/navigation'
import { onMount } from 'svelte'
import AdminPage from '$lib/components/admin/AdminPage.svelte'
import EnhancedComposer from '$lib/components/admin/EnhancedComposer.svelte'
import Composer from '$lib/components/admin/composer'
import PostMetadataPopover from '$lib/components/admin/PostMetadataPopover.svelte'
import Button from '$lib/components/admin/Button.svelte'
import PublishDropdown from '$lib/components/admin/PublishDropdown.svelte'
@ -199,7 +199,7 @@
{#if config?.showContent}
<div class="editor-wrapper">
<EnhancedComposer bind:data={content} placeholder="Start writing..." />
<Composer bind:data={content} placeholder="Start writing..." />
</div>
{/if}
</div>