mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: add alignment options to ImageBlock component for improved layout control
This commit is contained in:
parent
0b2c4d3ad1
commit
411845d480
2 changed files with 65 additions and 16 deletions
|
|
@ -17,6 +17,9 @@ export default Node.create({
|
||||||
size: {
|
size: {
|
||||||
width: 300,
|
width: 300,
|
||||||
},
|
},
|
||||||
|
alignment: {
|
||||||
|
default: 'center',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { NodeViewWrapper } from '@tiptap/react'
|
import { NodeViewWrapper } from '@tiptap/react'
|
||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import { Resizable } from 're-resizable'
|
import { Resizable } from 're-resizable'
|
||||||
import { AlertTriangle, Image, Download } from 'lucide-react'
|
import { AlertTriangle, Image, Download, AlignLeft, AlignCenter, AlignRight } from 'lucide-react'
|
||||||
import { uploadNewImageFile } from '../../../../../services/blocks/Image/images'
|
import { uploadNewImageFile } from '../../../../../services/blocks/Image/images'
|
||||||
import { getActivityBlockMediaDirectory } from '@services/media/media'
|
import { getActivityBlockMediaDirectory } from '@services/media/media'
|
||||||
import { useOrg } from '@components/Contexts/OrgContext'
|
import { useOrg } from '@components/Contexts/OrgContext'
|
||||||
|
|
@ -29,10 +29,12 @@ function ImageBlockComponent(props: any) {
|
||||||
const [imageSize, setImageSize] = React.useState({
|
const [imageSize, setImageSize] = React.useState({
|
||||||
width: props.node.attrs.size ? props.node.attrs.size.width : 300,
|
width: props.node.attrs.size ? props.node.attrs.size.width : 300,
|
||||||
})
|
})
|
||||||
|
const [alignment, setAlignment] = React.useState(props.node.attrs.alignment || 'center')
|
||||||
|
|
||||||
const fileId = blockObject
|
const fileId = blockObject
|
||||||
? `${blockObject.content.file_id}.${blockObject.content.file_format}`
|
? `${blockObject.content.file_id}.${blockObject.content.file_format}`
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const handleImageChange = (event: React.ChangeEvent<any>) => {
|
const handleImageChange = (event: React.ChangeEvent<any>) => {
|
||||||
setImage(event.target.files[0])
|
setImage(event.target.files[0])
|
||||||
}
|
}
|
||||||
|
|
@ -49,6 +51,7 @@ function ImageBlockComponent(props: any) {
|
||||||
props.updateAttributes({
|
props.updateAttributes({
|
||||||
blockObject: object,
|
blockObject: object,
|
||||||
size: imageSize,
|
size: imageSize,
|
||||||
|
alignment: alignment,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,8 +78,26 @@ function ImageBlockComponent(props: any) {
|
||||||
document.body.removeChild(link);
|
document.body.removeChild(link);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleAlignmentChange = (newAlignment: string) => {
|
||||||
|
setAlignment(newAlignment);
|
||||||
|
props.updateAttributes({
|
||||||
|
alignment: newAlignment,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {}, [course, org])
|
useEffect(() => {}, [course, org])
|
||||||
|
|
||||||
|
const getAlignmentClass = () => {
|
||||||
|
switch (alignment) {
|
||||||
|
case 'left':
|
||||||
|
return 'justify-start';
|
||||||
|
case 'right':
|
||||||
|
return 'justify-end';
|
||||||
|
default:
|
||||||
|
return 'justify-center';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper className="block-image w-full">
|
<NodeViewWrapper className="block-image w-full">
|
||||||
<FileUploadBlock isEditable={isEditable} isLoading={isLoading} isEmpty={!blockObject} Icon={Image}>
|
<FileUploadBlock isEditable={isEditable} isLoading={isLoading} isEmpty={!blockObject} Icon={Image}>
|
||||||
|
|
@ -85,7 +106,7 @@ function ImageBlockComponent(props: any) {
|
||||||
</FileUploadBlock>
|
</FileUploadBlock>
|
||||||
|
|
||||||
{blockObject && isEditable && (
|
{blockObject && isEditable && (
|
||||||
<div className="w-full flex justify-center">
|
<div className={`w-full flex ${getAlignmentClass()}`}>
|
||||||
<Resizable
|
<Resizable
|
||||||
defaultSize={{ width: imageSize.width, height: '100%' }}
|
defaultSize={{ width: imageSize.width, height: '100%' }}
|
||||||
handleStyles={{
|
handleStyles={{
|
||||||
|
|
@ -123,6 +144,7 @@ function ImageBlockComponent(props: any) {
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<div className="relative">
|
||||||
<img
|
<img
|
||||||
src={`${getActivityBlockMediaDirectory(
|
src={`${getActivityBlockMediaDirectory(
|
||||||
org?.org_uuid,
|
org?.org_uuid,
|
||||||
|
|
@ -136,12 +158,36 @@ function ImageBlockComponent(props: any) {
|
||||||
className="rounded-lg shadow-sm max-w-full h-auto"
|
className="rounded-lg shadow-sm max-w-full h-auto"
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
/>
|
/>
|
||||||
|
<div className="absolute top-2 right-2 flex items-center gap-1.5 bg-white bg-opacity-90 backdrop-blur-xs rounded-lg p-1 shadow-xs transition-opacity opacity-70 hover:opacity-100">
|
||||||
|
<button
|
||||||
|
onClick={() => handleAlignmentChange('left')}
|
||||||
|
className={`p-1.5 rounded-md hover:bg-gray-100 text-gray-600 ${alignment === 'left' ? 'bg-gray-100' : ''}`}
|
||||||
|
title="Align left"
|
||||||
|
>
|
||||||
|
<AlignLeft size={16} />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleAlignmentChange('center')}
|
||||||
|
className={`p-1.5 rounded-md hover:bg-gray-100 text-gray-600 ${alignment === 'center' ? 'bg-gray-100' : ''}`}
|
||||||
|
title="Center align"
|
||||||
|
>
|
||||||
|
<AlignCenter size={16} />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleAlignmentChange('right')}
|
||||||
|
className={`p-1.5 rounded-md hover:bg-gray-100 text-gray-600 ${alignment === 'right' ? 'bg-gray-100' : ''}`}
|
||||||
|
title="Align right"
|
||||||
|
>
|
||||||
|
<AlignRight size={16} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</Resizable>
|
</Resizable>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{blockObject && !isEditable && (
|
{blockObject && !isEditable && (
|
||||||
<div className="w-full flex justify-center">
|
<div className={`w-full flex ${getAlignmentClass()}`}>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<img
|
<img
|
||||||
src={`${getActivityBlockMediaDirectory(
|
src={`${getActivityBlockMediaDirectory(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue