schlechtenburg/packages/image/lib/edit.tsx

120 lines
2.7 KiB
TypeScript
Raw Normal View History

2020-05-24 22:52:33 +02:00
import {
2020-12-30 02:32:46 +01:00
defineComponent,
2020-05-24 22:52:33 +02:00
reactive,
ref,
Ref,
watch,
PropType,
2020-12-27 22:32:43 +01:00
} from 'vue';
2020-05-24 22:52:33 +02:00
import {
model,
2020-12-30 14:34:23 +01:00
SbToolbar,
SbButton,
2021-03-08 16:29:35 +01:00
SbBlock,
IBlockData,
2022-03-12 17:16:24 +01:00
OnUpdateSelfCb,
2020-12-30 14:34:23 +01:00
} from '@schlechtenburg/core';
2022-03-11 18:23:14 +01:00
import { IParagraphData } from '@schlechtenburg/paragraph';
2020-05-24 22:52:33 +02:00
import {
getDefaultData,
2022-03-11 18:23:14 +01:00
IImageData,
2020-05-24 22:52:33 +02:00
} from './util';
import './style.scss';
2020-12-30 02:32:46 +01:00
export default defineComponent({
2020-05-24 22:52:33 +02:00
name: 'sb-image-edit',
model,
props: {
2022-03-12 17:16:24 +01:00
onUpdate: {
type: (null as unknown) as PropType<OnUpdateSelfCb<IImageData>>,
default: () => {},
},
2020-05-24 22:52:33 +02:00
data: {
2022-03-11 18:23:14 +01:00
type: (null as unknown) as PropType<IImageData>,
2020-05-24 22:52:33 +02:00
default: getDefaultData,
},
},
2021-03-08 16:29:35 +01:00
setup(props) {
2020-05-24 22:52:33 +02:00
const localData = reactive({
src: props.data.src,
alt: props.data.alt,
2020-12-30 02:32:46 +01:00
description: props.data.description,
2020-05-24 22:52:33 +02:00
});
const fileInput: Ref<null|HTMLInputElement> = ref(null);
watch(() => props.data, () => {
localData.src = props.data.src;
localData.alt = props.data.alt;
2020-12-30 02:32:46 +01:00
localData.description = props.data.description;
2020-05-24 22:52:33 +02:00
});
const selectImage = () => {
if (fileInput.value) {
fileInput.value.click();
}
};
const onImageSelect = () => {
if (fileInput.value && fileInput.value.files && fileInput.value.files.length) {
2020-05-27 17:32:35 +02:00
const reader = new FileReader();
reader.addEventListener('load', () => {
2021-03-08 16:29:35 +01:00
const src = reader?.result?.toString();
if (!src) {
throw new Error('Couldn\'t load image src');
}
2021-02-22 19:13:37 +01:00
props.onUpdate({
2021-03-08 16:29:35 +01:00
src,
2020-05-27 17:32:35 +02:00
alt: props.data.alt,
2020-12-30 02:32:46 +01:00
description: props.data.description,
2020-05-27 17:32:35 +02:00
});
2020-05-27 15:57:57 +02:00
});
2020-05-27 17:32:35 +02:00
reader.readAsDataURL(fileInput.value.files[0]);
2020-05-24 22:52:33 +02:00
}
};
2022-03-11 18:23:14 +01:00
const onDescriptionUpdate = (description: IBlockData<IParagraphData>) => {
2021-02-22 19:13:37 +01:00
props.onUpdate({
2020-12-30 02:32:46 +01:00
...props.data,
description,
});
};
2020-05-25 23:10:21 +02:00
return () => (
2020-12-30 02:32:46 +01:00
<figure class="sb-image">
2020-05-24 22:52:33 +02:00
<SbToolbar>
2020-05-27 20:36:46 +02:00
{localData.src
2021-03-08 17:45:21 +01:00
? <SbButton {...{ onClick: selectImage }}>Select Image</SbButton>
2020-05-27 20:36:46 +02:00
: null}
2020-05-24 22:52:33 +02:00
<input
type="file"
2020-12-30 02:32:46 +01:00
ref={fileInput}
2020-05-24 22:52:33 +02:00
style="display: none;"
2020-05-27 20:36:46 +02:00
onInput={onImageSelect}
2020-05-24 22:52:33 +02:00
/>
</SbToolbar>
2020-05-25 23:10:21 +02:00
{localData.src
2020-12-30 02:32:46 +01:00
? <>
<img
src={localData.src}
alt={localData.alt}
class="sb-image__content"
/>
<SbBlock
block={localData.description}
2022-03-11 18:23:14 +01:00
onUpdate={(updated: IBlockData<IParagraphData>) => onDescriptionUpdate(updated)}
2020-12-30 02:32:46 +01:00
/>
</>
2021-03-08 17:45:21 +01:00
: <SbButton {...{ onClick: selectImage }}>Select Image</SbButton>
2021-03-08 16:29:35 +01:00
}
2020-12-30 02:32:46 +01:00
</figure>
2020-05-24 22:52:33 +02:00
);
},
});