feat(course): crop cover image to 280x200 on upload
The course cover Upload tab stored the raw file and relied on CSS object-cover to fake the 280x200 frame at display time. Route uploads through the existing ImageCropper at a 280/200 aspect ratio so the saved asset matches the frame. Also teach the cropper UploadTrigger to accept drag-and-drop so the prior drop-to-upload UX is preserved.
This commit is contained in:
@@ -3,11 +3,13 @@
|
||||
import type { ImageCropperUploadTriggerProps } from './types';
|
||||
import { cn } from '../../tools';
|
||||
|
||||
let { ref = $bindable(null), children, ...rest }: ImageCropperUploadTriggerProps = $props();
|
||||
let { ref = $bindable(null), class: className, children, ...rest }: ImageCropperUploadTriggerProps = $props();
|
||||
|
||||
const triggerState = useImageCropperTrigger();
|
||||
const isDisabled = $derived(triggerState.rootState.disabled);
|
||||
|
||||
let isDragging = $state(false);
|
||||
|
||||
function handleClick(e: MouseEvent) {
|
||||
if (isDisabled) {
|
||||
e.preventDefault();
|
||||
@@ -15,6 +17,28 @@
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function handleDragOver(e: DragEvent) {
|
||||
if (isDisabled) return;
|
||||
|
||||
e.preventDefault();
|
||||
isDragging = true;
|
||||
}
|
||||
|
||||
function handleDragLeave() {
|
||||
isDragging = false;
|
||||
}
|
||||
|
||||
function handleDrop(e: DragEvent) {
|
||||
isDragging = false;
|
||||
if (isDisabled) return;
|
||||
|
||||
const file = e.dataTransfer?.files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
e.preventDefault();
|
||||
triggerState.rootState.onUpload(file);
|
||||
}
|
||||
</script>
|
||||
|
||||
<label
|
||||
@@ -22,7 +46,15 @@
|
||||
bind:this={ref}
|
||||
for={isDisabled ? undefined : triggerState.rootState.id}
|
||||
onclick={handleClick}
|
||||
class={cn('ui:cursor-pointer', isDisabled ? 'ui:cursor-not-allowed ui:opacity-50 ui:pointer-events-none' : '')}
|
||||
ondragover={handleDragOver}
|
||||
ondragleave={handleDragLeave}
|
||||
ondrop={handleDrop}
|
||||
class={cn(
|
||||
'ui:cursor-pointer',
|
||||
isDisabled ? 'ui:cursor-not-allowed ui:opacity-50 ui:pointer-events-none' : '',
|
||||
isDragging ? 'ui:ring-2 ui:ring-primary' : '',
|
||||
className
|
||||
)}
|
||||
aria-disabled={isDisabled}
|
||||
>
|
||||
{@render children?.()}
|
||||
|
||||
Reference in New Issue
Block a user