Skip to content

Commit

Permalink
Merge next in main (#533)
Browse files Browse the repository at this point in the history
* fix(app): canvas export image content is not rendered if it's higher than viewport
* fix(app): fix custom editor initial value
* fix(dom-export): reduce dom-export timeout
* Create early-snails-leave.md
  • Loading branch information
riccardoperra authored May 21, 2023
1 parent a8a9ee5 commit 15312cd
Show file tree
Hide file tree
Showing 15 changed files with 702 additions and 238 deletions.
6 changes: 6 additions & 0 deletions .changeset/early-snails-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@codeimage/app": patch
"@codeimage/dom-export": patch
---

fix(app): canvas export image content is not rendered if it's higher than viewport
2 changes: 1 addition & 1 deletion apps/codeimage/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
"modern-normalize": "^1.1.0",
"polished": "^4.2.2",
"rxjs": "^7.8.0",
"solid-codemirror": "^2.2.3",
"solid-codemirror": "^2.3.0",
"solid-headless": "^0.13.0",
"solid-js": "^1.7.3",
"solid-use": "^0.5.0",
Expand Down
73 changes: 73 additions & 0 deletions apps/codeimage/src/components/CustomEditor/CanvasEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {getRootEditorStore} from '@codeimage/store/editor';
import {getActiveEditorStore} from '@codeimage/store/editor/activeEditor';
import {EditorView} from '@codemirror/view';
import {
createCompartmentExtension,
createEditorControlledValue,
createEditorFocus,
} from 'solid-codemirror';
import {Accessor, createEffect, createSignal, on} from 'solid-js';
import CustomEditor from './CustomEditor';

interface CanvasEditorProps {
readOnly: boolean;
}

export default function CanvasEditor(props: CanvasEditorProps) {
const [editorView, setEditorView] = createSignal<EditorView>();
const activeEditorStore = getActiveEditorStore();
const {
state: editorState,
actions: {setFocused},
} = getRootEditorStore();

const {setFocused: editorSetFocused} = createEditorFocus(
editorView as Accessor<EditorView>,
focusing => setFocused(focusing),
);

createEffect(
on(
editorView,
view => {
if (!view) return;
createEffect(
on(
() => editorState.options.focused,
isFocused => {
if (view && !view.hasFocus && isFocused) {
editorSetFocused(true);
}
},
),
);
},
{defer: true},
),
);

createCompartmentExtension(
() =>
EditorView.domEventHandlers({
paste(event, view) {
setTimeout(() => {
const localValue = view.state.doc.toString();
activeEditorStore.format(localValue);
});
},
}),
editorView,
);

createEditorControlledValue(
editorView as Accessor<EditorView>,
() => activeEditorStore.editor()?.code ?? '',
);

return (
<CustomEditor
onEditorViewChange={setEditorView}
readOnly={props.readOnly}
/>
);
}
68 changes: 17 additions & 51 deletions apps/codeimage/src/components/CustomEditor/CustomEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,12 @@ import {
rectangularSelection,
} from '@codemirror/view';
import {SUPPORTED_FONTS} from '@core/configuration/font';
import {
createCodeMirror,
createEditorControlledValue,
createEditorFocus,
createEditorReadonly,
} from 'solid-codemirror';
import {createCodeMirror, createEditorReadonly} from 'solid-codemirror';
import {
createEffect,
createMemo,
createResource,
on,
onMount,
VoidProps,
} from 'solid-js';
import {createTabIcon} from '../../hooks/use-tab-icon';
Expand Down Expand Up @@ -66,19 +60,15 @@ const EDITOR_BASE_SETUP: Extension = [

interface CustomEditorProps {
readOnly: boolean;
onEditorViewChange?: (view: EditorView | undefined) => void;
}

export default function CustomEditor(props: VoidProps<CustomEditorProps>) {
let editorEl!: HTMLDivElement;
const {themeArray: themes} = getThemeStore();
const languages = SUPPORTED_LANGUAGES;
const fonts = SUPPORTED_FONTS;

const {
state: editorState,
actions: {setFocused},
} = getRootEditorStore();
const {editor, setCode} = getActiveEditorStore();
const {state: editorState, canvasEditorEvents} = getRootEditorStore();
const {editor} = getActiveEditorStore();
const selectedLanguage = createMemo(() =>
languages.find(language => language.id === editor()?.languageId),
);
Expand All @@ -89,9 +79,11 @@ export default function CustomEditor(props: VoidProps<CustomEditorProps>) {
createExtension,
} = createCodeMirror({
value: editor()?.code,
onValueChange: setCode,
onTransactionDispatched: tr => canvasEditorEvents.emit(tr),
});

createEffect(() => props.onEditorViewChange?.(editorView()));

const [currentLanguage] = createResource(selectedLanguage, ({plugin}) =>
plugin(),
);
Expand Down Expand Up @@ -167,16 +159,6 @@ export default function CustomEditor(props: VoidProps<CustomEditorProps>) {
});
};

onMount(() => {
setRef(() => editorEl);
});

const {setFocused: editorSetFocused} = createEditorFocus(
editorView,
setFocused,
);

createEditorControlledValue(editorView, () => editor()?.code ?? '');
createEditorReadonly(editorView, () => props.readOnly);
createExtension(EditorView.lineWrapping);
createExtension(() =>
Expand All @@ -192,38 +174,22 @@ export default function CustomEditor(props: VoidProps<CustomEditorProps>) {
);
createExtension(() => themeConfiguration()?.editorTheme || []);
createExtension(baseTheme);
createExtension(EDITOR_BASE_SETUP);
createExtension(() =>
EditorView.domEventHandlers({
paste(event, view) {
setTimeout(() => {
const localValue = view.state.doc.toString();
getActiveEditorStore().format(localValue);
});
},
}),
);

const reconfigureBaseSetup = createExtension(EDITOR_BASE_SETUP);

createEffect(
on(editorView, view => {
if (view) {
createEffect(
on(
() => editorState.options.focused,
isFocused => {
if (view && !view.hasFocus && isFocused) {
editorSetFocused(true);
}
},
),
);
}
}),
on(
() => props.readOnly,
readOnly => {
const extension = readOnly ? [] : EDITOR_BASE_SETUP;
reconfigureBaseSetup(extension);
},
),
);

return (
<code class={`language-${selectedLanguage()?.id ?? 'default'}`}>
<div ref={ref => (editorEl = ref)} />
<div ref={setRef} />
</code>
);
}
32 changes: 32 additions & 0 deletions apps/codeimage/src/components/CustomEditor/PreviewExportEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {getRootEditorStore} from '@codeimage/store/editor';
import {Annotation, Transaction} from '@codemirror/state';
import {EditorView} from '@codemirror/view';
import {createEffect, createSignal, lazy, on} from 'solid-js';

const syncAnnotation = Annotation.define<boolean>();

function syncDispatch(tr: Transaction, other: EditorView) {
if (!tr.changes.empty && !tr.annotation(syncAnnotation)) {
const annotations: Annotation<unknown>[] = [syncAnnotation.of(true)];
const userEvent = tr.annotation(Transaction.userEvent);
if (userEvent) annotations.push(Transaction.userEvent.of(userEvent));
other.dispatch({changes: tr.changes, annotations});
}
}

const CustomEditor = lazy(() => import('./CustomEditor'));

export default function PreviewExportEditor() {
const [editorView, setEditorView] = createSignal<EditorView>();

createEffect(
on(editorView, editorView => {
if (!editorView) return;
getRootEditorStore().canvasEditorEvents.listen(tr => {
setTimeout(() => syncDispatch(tr, editorView), 250);
});
}),
);

return <CustomEditor onEditorViewChange={setEditorView} readOnly={true} />;
}
2 changes: 2 additions & 0 deletions apps/codeimage/src/components/Frame/Frame.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export const previewPortal = style({
width: 'auto',
height: 'auto',
opacity: 0,
transform: `scale(0.01)`,
transformOrigin: 'left top',
});

export const container = style([
Expand Down
14 changes: 9 additions & 5 deletions apps/codeimage/src/components/Frame/FrameHandler.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@ export const wrapper = style([
{
width: '100%',
height: '100%',
display: 'flex',
display: 'grid',
overflowY: 'auto',
overflowX: 'hidden',
flex: '1',
alignItems: 'center',
justifyContent: 'center',
'@supports': {
'(scrollbar-gutter: stable)': {
paddingRight: 0,
scrollbarGutter: 'stable',
},
},
selectors: {
...withThemeMode({
dark: {
Expand All @@ -38,20 +44,18 @@ export const wrapper = style([

export const handler = style([
{
// TODO: this is a workaround to fix gutters and cursor in mobile view
// zoom: `${frameHandlerVars.scale}`,
display: 'block',
justifyContent: 'center',
position: 'relative',
transformOrigin: 'center',
marginBottom: '80px',
},
]);

export const content = style({
position: 'relative',
width: '100%',
height: '100%',
marginBottom: '40px',
position: 'relative',
});

export const squaredBackgroundOverlay = style({
Expand Down
9 changes: 6 additions & 3 deletions apps/codeimage/src/components/Frame/FrameSkeleton.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const wrapper = style([
backgroundColor: themeVars.backgroundColor.gray['100'],
},
dark: {
backgroundColor: darkGrayScale.gray3,
backgroundColor: darkGrayScale.gray2,
},
}),
},
Expand All @@ -32,13 +32,16 @@ export const terminal = {
base: style([
terminalStyle.terminalTheme,
{
borderRadius: themeVars.borderRadius.md,
overflow: 'hidden',
selectors: {
...withThemeMode({
light: {
backgroundColor: themeVars.backgroundColor.gray['200'],
},
dark: {
backgroundColor: darkGrayScale.gray2,
backgroundColor: darkGrayScale.gray1,
border: `1px solid ${darkGrayScale.gray3}`,
},
}),
},
Expand All @@ -54,7 +57,7 @@ export const terminal = {
backgroundColor: themeVars.backgroundColor.gray['400'],
},
dark: {
backgroundColor: darkGrayScale.gray6,
backgroundColor: darkGrayScale.gray2,
},
}),
},
Expand Down
4 changes: 2 additions & 2 deletions apps/codeimage/src/components/Frame/ManagedFrame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {lazy, Show} from 'solid-js';
import {DynamicTerminal} from '../Terminal/DynamicTerminal/DynamicTerminal';
import {Frame} from './Frame';

const CustomEditor = lazy(() => import('../CustomEditor/CustomEditor'));
const CanvasEditor = lazy(() => import('../CustomEditor/CanvasEditor'));

export function ManagedFrame() {
const frame = getFrameState().store;
Expand Down Expand Up @@ -41,7 +41,7 @@ export function ManagedFrame() {
themeId={editor.state.options.themeId}
>
<Show when={getActiveEditorStore().editor()}>
<CustomEditor readOnly={readOnly()} />
<CanvasEditor readOnly={readOnly()} />
</Show>
</DynamicTerminal>
</Frame>
Expand Down
Loading

0 comments on commit 15312cd

Please sign in to comment.