Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce an ImageContent component in editor #328

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions packages/react/src/core/CodeMirrorEditor/ImageContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Based on https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types
* Removing svg, which is not binary.
*/
const binaryImageExtensions = new Set(['apng', 'png', 'avif', 'gif', 'jpg', 'jpeg', 'jfif', 'pjpeg', 'pjp', 'webp']);

export function uint8ArrayToDataUrl(arr: Uint8Array) {
return URL.createObjectURL(new Blob([arr.buffer]));
}
export function isBinaryImagePath(filePath: string) {
const split = filePath.split('.');

if (split.length < 2) {
return false;
}

const ext = split[split.length - 1];

return binaryImageExtensions.has(ext);
}

export function ImageContent({ src }: { src: string }) {
return <img src={src} />;
}
Comment on lines +22 to +24
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problems left:
somehow the editor displays code from another file alongside the image

The existing <BinaryContent /> does too, but it uses position: absolute; inset: 0 to cover the text area. We could do same here:

Suggested change
export function ImageContent({ src }: { src: string }) {
return <img src={src} />;
}
export function ImageContent({ src }: { src: string }) {
return (
<div className="flex items-center justify-center absolute inset-0 z-10 bg-tk-elements-app-backgroundColor">
<img src={src} />
</div>
);
}

This isn't actually good approach as the text content of previous file is still present in DOM. It's part of tab and read order so users can actually navigate to this invisible element. But as this bug is already present in TutorialKit we can ignore it on this PR. 🤷‍♂️

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a leftover of a time where we were trying to cache the EditorView from CodeMirror which I don't think is necessary. We should change the logic so that the CodeMirrorEditor is not rendered in that case.

8 changes: 7 additions & 1 deletion packages/react/src/core/CodeMirrorEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { BinaryContent } from './BinaryContent.js';
import { getTheme, reconfigureTheme } from './cm-theme.js';
import { indentKeyBinding } from './indent.js';
import { getLanguage } from './languages.js';
import { isBinaryImagePath, ImageContent, uint8ArrayToDataUrl } from './ImageContent.js';

export interface EditorDocument {
value: string | Uint8Array;
Expand Down Expand Up @@ -90,6 +91,7 @@ export function CodeMirrorEditor({
const onChangeRef = useRef(onChange);

const isBinaryFile = doc?.value instanceof Uint8Array;
const isBinaryImageFile = isBinaryFile && doc?.filePath && isBinaryImagePath(doc?.filePath);

onScrollRef.current = onScroll;
onChangeRef.current = onChange;
Expand Down Expand Up @@ -187,7 +189,11 @@ export function CodeMirrorEditor({

return (
<div className={classNames('relative', className)}>
{isBinaryFile && <BinaryContent />}
{isBinaryImageFile ? (
<ImageContent src={uint8ArrayToDataUrl(doc?.value as Uint8Array)} />
) : isBinaryFile ? (
<BinaryContent />
) : null}
<div className="h-full overflow-hidden" ref={containerRef} />
</div>
);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading