Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Commit

Permalink
refactor(preview): move all react dependent stuff in react-preview file
Browse files Browse the repository at this point in the history
  • Loading branch information
Lasse Kuechler authored and lkuechler committed Mar 12, 2018
1 parent f8d2b6b commit 08cd6f5
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 143 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"appId": "io.github.meetalva",
"productName": "Alva",
"copyright": "Copyright (c) 2017 SinnerSchrader Deutschland GmbH",
"npmArgs": "npm i @types/react",
"files": [
"build/**/*",
"package.json",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
import { action, observable } from 'mobx';
import { observer } from 'mobx-react';
import { Page } from '../../store/page/page';
import { PageElement } from '../../store/page/page-element';
import { PropertyValue } from '../../store/page/property-value';
import * as React from 'react';
import * as ReactDOM from 'react-dom';

import { Page } from '../../../store/page/page';
import { PageElement } from '../../../store/page/page-element';
import { PropertyValue } from '../../../store/page/property-value';
import { Store } from '../../../store/store';

import { HighlightAreaProps, HighlightElementFunction } from '../../preview';

export interface PreviewAppProps {
store: Store;
highlightElement: HighlightElementFunction;
}

export interface PreviewAppState {
page?: Page;
}

interface PreviewProps {
page?: Page;
selectedElementId?: number[];
highlightElement: HighlightElementFunction;
}

interface PatternWrapperState {
errorMessage?: string;
}

class PatternWrapper extends React.Component<{}, PatternWrapperState> {
public constructor(props: {}) {
super(props);
Expand All @@ -25,18 +48,10 @@ class PatternWrapper extends React.Component<{}, PatternWrapperState> {
}
}

export interface HighlightAreaProps extends ClientRect {
opacity?: number;
}

export interface PreviewProps {
page?: Page;
selectedElementId?: number[];
}

@observer
export class Preview extends React.Component<PreviewProps> {
class Preview extends React.Component<PreviewProps> {
private patternFactories: { [id: string]: React.StatelessComponent | ObjectConstructor };
private patternWrapperRef: PatternWrapper;
@observable private highlightArea: HighlightAreaProps;

public constructor(props: PreviewProps) {
Expand All @@ -52,6 +67,23 @@ export class Preview extends React.Component<PreviewProps> {
top: 0,
width: 0
};

this.highlightElementCallback = this.highlightElementCallback.bind(this);
}

public componentDidMount(): void {
this.triggerHighlight();
}

public componentDidUpdate(): void {
this.triggerHighlight();
}

private triggerHighlight(): void {
const domNode = this.patternWrapperRef && ReactDOM.findDOMNode(this.patternWrapperRef);
if (domNode) {
this.props.highlightElement(domNode, this.highlightArea, this.highlightElementCallback);
}
}

public render(): JSX.Element | null {
Expand Down Expand Up @@ -162,14 +194,7 @@ export class Preview extends React.Component<PreviewProps> {
return (
<PatternWrapper
key={key}
ref={(el: PatternWrapper) => {
const domNode = ReactDOM.findDOMNode(el);
if (!domNode) {
return;
}

this.highlightElement(domNode);
}}
ref={(ref: PatternWrapper) => (this.patternWrapperRef = ref)}
>
{reactComponent}
</PatternWrapper>
Expand All @@ -191,47 +216,38 @@ export class Preview extends React.Component<PreviewProps> {
}

@action
private highlightElement(element: Element): void {
const highlightArea: HighlightAreaProps = this.highlightArea;
const clientRect: ClientRect = element.getBoundingClientRect();
const newHighlightArea: HighlightAreaProps = {
bottom: clientRect.bottom,
height: clientRect.height,
left: clientRect.left + window.scrollX,
opacity: 1,
right: clientRect.right,
top: clientRect.top + window.scrollY,
width: clientRect.width
};

if (
newHighlightArea.top === highlightArea.top &&
newHighlightArea.right === highlightArea.right &&
newHighlightArea.bottom === highlightArea.bottom &&
newHighlightArea.left === highlightArea.left &&
newHighlightArea.height === highlightArea.height &&
newHighlightArea.width === highlightArea.width
) {
return;
private highlightElementCallback(newHighlightArea: HighlightAreaProps): void {
if (newHighlightArea) {
this.highlightArea = newHighlightArea;
}

element.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'nearest'
});

this.highlightArea = newHighlightArea;

setTimeout(() => this.hideHighlightArea(), 500);
}
}

@action
private hideHighlightArea(): void {
this.highlightArea.opacity = 0;
@observer
export class PreviewApp extends React.Component<PreviewAppProps, PreviewAppState> {
public constructor(props: PreviewAppProps) {
super(props);
}
}

interface PatternWrapperState {
errorMessage?: string;
public render(): JSX.Element {
let DevTools;
try {
const DevToolsExports = require('mobx-react-devtools');
DevTools = DevToolsExports ? DevToolsExports.default : undefined;
} catch (error) {
// Ignored
}

const selectedElement: PageElement | undefined = this.props.store.getSelectedElement();
return (
<div>
<Preview
page={this.props.store.getCurrentPage()}
selectedElementId={selectedElement && selectedElement.getId()}
highlightElement={this.props.highlightElement}
/>
{DevTools ? <DevTools /> : ''}
</div>
);
}
}
13 changes: 13 additions & 0 deletions src/component/presentation/react/render.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as React from 'react';
import * as ReactDom from 'react-dom';

import { PreviewApp } from './preview';
import { HighlightElementFunction } from '../../preview';
import { Store } from '../../../store/store';

export const renderReact = (store: Store, highlightElement: HighlightElementFunction) => {
ReactDom.render(
<PreviewApp store={store} highlightElement={highlightElement} />,
document.getElementById('app')
);
};
93 changes: 93 additions & 0 deletions src/component/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { ipcRenderer } from 'electron';
import { JsonObject } from '../store/json';
import { renderReact } from './presentation/react/render';
import * as SmoothscrollPolyfill from 'smoothscroll-polyfill';
import { Store } from '../store/store';

export interface HighlightAreaProps extends ClientRect {
opacity?: number;
}

export type HighlightElementFunction = (
element: Element,
currentHighlightArea: HighlightAreaProps,
callback: (newHighlightArea: HighlightAreaProps) => void
) => void;

const store = new Store();

ipcRenderer.on('page-change', (event: {}, message: JsonObject) => {
store.setPageFromJsonInternal(message.page as JsonObject, message.pageId as string);
});

ipcRenderer.on('open-styleguide', (event: {}, message: JsonObject) => {
store.openStyleguide(message.styleGuidePath as string);
});

ipcRenderer.on('selectedElement-change', (event: {}, message: JsonObject) => {
store.setSelectedElementById(message.selectedElementId as number[]);
});

const highlightElement: HighlightElementFunction = (element, currentHighlightArea, callback) => {
const clientRect: ClientRect = element.getBoundingClientRect();
const newHighlightArea: HighlightAreaProps = {
bottom: clientRect.bottom,
height: clientRect.height,
left: clientRect.left + window.scrollX,
opacity: 1,
right: clientRect.right,
top: clientRect.top + window.scrollY,
width: clientRect.width
};

if (
newHighlightArea.top === currentHighlightArea.top &&
newHighlightArea.right === currentHighlightArea.right &&
newHighlightArea.bottom === currentHighlightArea.bottom &&
newHighlightArea.left === currentHighlightArea.left &&
newHighlightArea.height === currentHighlightArea.height &&
newHighlightArea.width === currentHighlightArea.width
) {
return;
}

element.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'nearest'
});

setTimeout(() => hideHighlightArea(newHighlightArea, callback), 500);
callback(newHighlightArea);
};

function hideHighlightArea(
highlightArea: HighlightAreaProps,
callback: (highlightArea: HighlightAreaProps) => void
): void {
const newHighlightArea = highlightArea;
newHighlightArea.opacity = 0;

callback(newHighlightArea);
}

window.onload = () => {
SmoothscrollPolyfill.polyfill();
renderReact(store, highlightElement);
};

// Disable drag and drop from outside the application
document.addEventListener(
'dragover',
event => {
event.preventDefault();
},
false
);
document.addEventListener(
'drop',
event => {
event.preventDefault();
},
false
);
84 changes: 0 additions & 84 deletions src/component/preview.tsx

This file was deleted.

0 comments on commit 08cd6f5

Please sign in to comment.