codeimage
codeimage copied to clipboard
🐞 - Broken code mirror cursor and line numbers on scaled content
~Added to fix mobile editor cursor and gutter when scaling the content, should be removed since it is an experimental property~.
Edit: After an investigation, it seems that there is a browser issue with "getBoundingClientRects"that returns inconsistent values when the parent node has the transform scale property.
This could be fixed wrapping the scaled content into an iframe. This could be a possible implementation that doesn't cover these issues:
- Stylesheet are not fully loaded. When switching a theme that uses @emotion/css the stylesheet must be loaded into the iframe.
- Iframe position must be changered.
- Frame handler size could be fixed
Possible implementation: create a new app package that handle only his style and the editor content
// IFrame.tsx
type IFrameProps = JSX.IntrinsicElements['iframe'] & {};
export function IFrame(props: IFrameProps): JSX.Element {
const [ref, setRef] = createSignal<HTMLIFrameElement>();
const [mountNode, setMountNode] = createSignal<HTMLElement>();
const [height, setHeight] = createSignal(0);
const [width, setWidth] = createSignal(0);
createEffect(
on(ref, frame => {
if (!frame || !frame.contentWindow) return;
const currentHead = window.document.head;
frame.contentDocument!.head.innerHTML = currentHead.innerHTML;
setMountNode(() => frame.contentWindow?.document.body);
setTimeout(() => {
const scrollHeight = ref()?.contentWindow?.document.body.scrollHeight;
const scrollWidth = ref()?.contentWindow?.document.body.scrollWidth;
setHeight(scrollHeight ?? 0);
setWidth(scrollWidth ?? 0);
});
}),
);
return (
<iframe {...props} ref={setRef} width={width()} height={height()}>
<Show when={mountNode()}>
{node => <Portal mount={node}>{props.children}</Portal>}
</Show>
</iframe>
);
}
// FrameHandler.tsx
export function FrameHandler(
props: PropsWithChildren<FrameHandlerProps>,
): JSXElement {
const [internalRef, setInternalRef] = createSignal<HTMLDivElement>();
const [canvasScale, setCanvasScale] = createSignal(1);
const ratio = 0.1;
createEffect(
on([internalRef], ([frame]) => {
setTimeout(() => {
const scale = getScaleByRatio(
// TODO: should be a ref (?)
frame?.parentElement,
frame,
1 + ratio,
);
props.onScaleChange(scale);
setCanvasScale(scale);
});
}),
);
return (
<Box class={styles.wrapper}>
<div
class={styles.handler}
style={assignInlineVars({
[styles.frameHandlerVars.scale]: canvasScale().toString(),
})}
ref={createRef<'div'>(props, e => {
setInternalRef(() => e);
})}
>
<div use:exportExclude={true} class={styles.squaredBackgroundOverlay} />
<IFrame>{props.children}</IFrame>
</div>
</Box>
);
}
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
What about Monaco Editor which powers VS Code.
Monaco Editor is unusable on mobile, has a bigger bundle and currently there will be a lot of effort switching editor library 😅
This is something not blocking in my opinion then at the moment is not prioritized
Yeah you are right for now it can work out, its just the cursor position is bothering me!! 😅
P.S - No hurry but sometime take a look at this