fix: update components to use Svelte 5 snippets and fix editor content loading

- Convert Button component to use snippets instead of slots
- Update BaseDropdown and StatusDropdown to use new Button snippet syntax
- Add effect to watch for data changes in ComposerCore and update editor content
- Fix SVG component usage in Album component for Svelte 5 compatibility

🤖 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:22:19 -04:00
parent e64788962e
commit 639a4a2429
5 changed files with 68 additions and 39 deletions

View file

@ -165,9 +165,9 @@
class:playing={isPlaying}
>
{#if isPlaying}
<PauseIcon />
<svelte:component this={PauseIcon} />
{:else}
<PlayIcon />
<svelte:component this={PlayIcon} />
{/if}
</button>
{/if}

View file

@ -1,4 +1,5 @@
<script lang="ts">
import type { Snippet } from 'svelte'
import Button from './Button.svelte'
import DropdownMenuContainer from './DropdownMenuContainer.svelte'
@ -9,6 +10,8 @@
dropdownTriggerSize?: 'small' | 'medium' | 'large'
class?: string
onToggle?: (isOpen: boolean) => void
trigger: Snippet
dropdown?: Snippet
}
let {
@ -17,7 +20,9 @@
isLoading = false,
dropdownTriggerSize = 'large',
class: className = '',
onToggle
onToggle,
trigger,
dropdown
}: Props = $props()
function handleDropdownToggle(e: MouseEvent) {
@ -47,9 +52,9 @@
<div class="dropdown-container {className}">
<div class="dropdown-trigger">
<slot name="trigger" />
{@render trigger()}
{#if $$slots.dropdown}
{#if dropdown}
<Button
variant="ghost"
iconOnly
@ -59,22 +64,24 @@
{isLoading}
class="dropdown-toggle"
>
<svg slot="icon" width="12" height="12" viewBox="0 0 12 12" fill="none">
<path
d="M3 4.5L6 7.5L9 4.5"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
{#snippet icon()}
<svg width="12" height="12" viewBox="0 0 12 12" fill="none">
<path
d="M3 4.5L6 7.5L9 4.5"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
{/snippet}
</Button>
{/if}
</div>
{#if isOpen && $$slots.dropdown}
{#if isOpen && dropdown}
<DropdownMenuContainer>
<slot name="dropdown" />
{@render dropdown()}
</DropdownMenuContainer>
{/if}
</div>

View file

@ -1,5 +1,6 @@
<script lang="ts">
import type { HTMLButtonAttributes } from 'svelte/elements'
import type { Snippet } from 'svelte'
interface Props extends HTMLButtonAttributes {
variant?: 'primary' | 'secondary' | 'danger' | 'ghost' | 'text' | 'overlay' | 'danger-text'
@ -12,6 +13,8 @@
active?: boolean
href?: string
class?: string
icon?: Snippet
children?: Snippet
}
let {
@ -27,6 +30,7 @@
type = 'button',
href,
class: className = '',
icon,
children,
onclick,
...restProps
@ -60,8 +64,8 @@
})
// Handle icon slot positioning
const hasIcon = $derived(!!$$slots.icon)
const hasDefaultSlot = $derived(!!$$slots.default)
const hasIcon = $derived(!!icon)
const hasDefaultSlot = $derived(!!children)
const showSpinner = $derived(loading && !iconOnly)
</script>
@ -94,21 +98,21 @@
{#if hasIcon && iconPosition === 'left' && !iconOnly}
<span class="btn-icon-wrapper">
<slot name="icon" />
{@render icon()}
</span>
{/if}
{#if hasDefaultSlot && !iconOnly}
<span class="btn-label">
<slot />
{@render children()}
</span>
{:else if iconOnly && hasIcon}
<slot name="icon" />
{@render icon()}
{/if}
{#if hasIcon && iconPosition === 'right' && !iconOnly}
<span class="btn-icon-wrapper">
<slot name="icon" />
{@render icon()}
</span>
{/if}
</a>
@ -141,21 +145,21 @@
{#if hasIcon && iconPosition === 'left' && !iconOnly}
<span class="btn-icon-wrapper">
<slot name="icon" />
{@render icon()}
</span>
{/if}
{#if hasDefaultSlot && !iconOnly}
<span class="btn-label">
<slot />
{@render children()}
</span>
{:else if iconOnly && hasIcon}
<slot name="icon" />
{@render icon()}
{/if}
{#if hasIcon && iconPosition === 'right' && !iconOnly}
<span class="btn-icon-wrapper">
<slot name="icon" />
{@render icon()}
</span>
{/if}
</button>

View file

@ -55,18 +55,21 @@
{isLoading}
class="status-dropdown"
>
<Button
slot="trigger"
variant="primary"
buttonSize="large"
onclick={handlePrimaryAction}
disabled={disabled || isLoading}
>
{primaryAction.label}
</Button>
{#snippet trigger()}
<Button
variant="primary"
buttonSize="large"
onclick={handlePrimaryAction}
disabled={disabled || isLoading}
>
{#snippet children()}
{primaryAction.label}
{/snippet}
</Button>
{/snippet}
{#if hasDropdownContent}
<div slot="dropdown">
{#snippet dropdown()}
{#if hasDropdownContent}
{#each availableActions as action}
<DropdownItem onclick={() => handleDropdownAction(action.status)}>
{action.label}
@ -85,8 +88,8 @@
View on site
</a>
{/if}
</div>
{/if}
{/if}
{/snippet}
</BaseDropdown>
<style lang="scss">

View file

@ -71,6 +71,7 @@
let element = $state<HTMLElement>()
let isLoading = $state(true)
let initialized = false
let contentLoaded = false
const mediaSelectionState = $derived($mediaSelectionStore)
// Toolbar component ref
@ -161,6 +162,20 @@
}
}
// Watch for external data changes and update editor
$effect(() => {
if (editor && data && !contentLoaded) {
// Only update if the data has actual content (not just empty doc)
const hasContent = data.content && data.content.length > 0 &&
!(data.content.length === 1 && data.content[0].type === 'paragraph' && !data.content[0].content);
if (hasContent) {
editor.commands.setContent(data);
contentLoaded = true;
}
}
});
onMount(() => {
// Get extensions with custom options
const extensions = getEditorExtensions({