Skip to content

Commit

Permalink
feat: columns
Browse files Browse the repository at this point in the history
  • Loading branch information
singuerinc committed Oct 8, 2018
1 parent a910ea1 commit efaf21a
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 21 deletions.
14 changes: 14 additions & 0 deletions app/actions/columns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { IColumn } from '../components/column/IColumn';

export const ADD_COLUMN = 'ADD_COLUMN';
export const REMOVE_COLUMN = 'REMOVE_COLUMN';

export const addColumn = (grid: IColumn) => ({
type: ADD_COLUMN,
payload: grid
});

export const removeColumn = (grid: IColumn) => ({
type: REMOVE_COLUMN,
payload: grid
});
54 changes: 41 additions & 13 deletions app/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@ import * as R from 'ramda';
import * as React from 'react';
import { connect } from 'react-redux';
import styled from 'styled-components';
import { addColumn, removeColumn } from '../actions/columns';
import { addGrid, removeGrid } from '../actions/grids';
import { addGuide, removeGuide } from '../actions/guides';
import { toggleVisibility as toggleHelpVisibility } from '../actions/help';
import { addOnion, removeOnion } from '../actions/onions';
import { addRuler, removeRuler } from '../actions/rulers';
import { toggleVisibility as toggleToolsVisibility } from '../actions/tools';
import { Column } from '../components/column/Column';
import { Grid } from '../components/grid/Grid';
import Guide from '../components/guide/Guide';
import OnionImage from '../components/onionImage/OnionImage';
import Ruler from '../components/ruler/Ruler';
import { Guide } from '../components/guide/Guide';
import { OnionImage } from '../components/onionImage/OnionImage';
import { Ruler } from '../components/ruler/Ruler';
import { Toolbox } from '../components/toolbox/Toolbox';
import { AppStore } from '../reducers';
import { HelpStore } from '../reducers/help';
import { ToolsStore } from '../reducers/tools';
import { initializeAnalytics, track } from './core/analytics';
import { factory as GridFactory } from './grid/factory';
import { factory as ColumnFactory } from './column/factory';
import { IGrid } from './grid/IGrid';
import { factory as GuideFactory } from './guide/factory';
import { IGuide } from './guide/IGuide';
Expand All @@ -28,16 +31,20 @@ import { IOnionImage } from './onionImage/IOnionImage';
import { factory as RulerFactory } from './ruler/factory';
import { IRuler } from './ruler/IRuler';
import { Tool } from './toolbox/Tool';
import { IColumn } from './column/IColumn';

interface Props {
help: HelpStore;
tools: ToolsStore;
columns: IColumn[];
grids: IGrid[];
guides: IGuide[];
onions: IOnionImage[];
rulers: IRuler[];
addGrid: (grid: IGrid) => void;
removeGrid: (grid: IGrid) => void;
addColumn: (column: IColumn) => void;
removeColumn: (column: IColumn) => void;
addGuide: (guide: IGuide) => void;
removeGuide: (guide: IGuide) => void;
addOnion: (onion: IOnionImage) => void;
Expand Down Expand Up @@ -84,17 +91,21 @@ class AppView extends React.Component<Props> {
};

render() {
const { grids, guides, onions, rulers, tools, help } = this.props;
const { columns, grids, guides, onions, rulers, tools, help } = this.props;
const isToolsVisible = tools.visible;
const isHelpVisible = help.visible;
const isGridVisible = R.gt(R.length(grids), 0);
const isColumnVisible = R.gt(R.length(columns), 0);

return (
<>
<ToolsWrapper visible={isToolsVisible}>
{grids.map((grid: IGrid) => (
<Grid key={grid.id} {...grid} />
))}
{columns.map((column: IColumn) => (
<Column key={column.id} {...column} />
))}
{rulers.map((ruler: IRuler) => (
<Ruler
key={ruler.id}
Expand Down Expand Up @@ -133,23 +144,38 @@ class AppView extends React.Component<Props> {
y={10}
toggleVisibility={this._setVisible}
isStuffVisible={isToolsVisible}
isColumnVisible={isColumnVisible}
isGridVisible={isGridVisible}
create={this.create}
toggle={this._toggleGrid}
toggle={this._toggleTool}
toggleHelp={this._toggleHelp}
/>
</>
);
}

private _toggleGrid = () => {
const isGridVisible = R.gt(R.length(this.props.grids), 0);
if (isGridVisible) {
this.props.removeGrid(this.props.grids[0]);
track('tool', 'grid', 'remove');
} else {
this.props.addGrid(GridFactory());
track('tool', 'grid', 'add');
private _toggleTool = (tool: Tool) => {
switch (tool) {
case Tool.GRID:
const isGridVisible = R.gt(R.length(this.props.grids), 0);
if (isGridVisible) {
this.props.removeGrid(this.props.grids[0]);
track('tool', 'grid', 'remove');
} else {
this.props.addGrid(GridFactory());
track('tool', 'grid', 'add');
}
break;
case Tool.COLUMN:
const isColumnVisible = R.gt(R.length(this.props.columns), 0);
if (isColumnVisible) {
this.props.removeColumn(this.props.columns[0]);
track('tool', 'grid', 'remove');
} else {
this.props.addColumn(ColumnFactory());
track('tool', 'grid', 'add');
}
break;
}
};

Expand All @@ -169,6 +195,8 @@ const App = connect(
{
addGrid,
removeGrid,
addColumn,
removeColumn,
addGuide,
removeGuide,
addOnion,
Expand Down
24 changes: 24 additions & 0 deletions app/components/column/Column.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from 'react';
import styled from 'styled-components';
import { IColumn } from './IColumn';
import { createColumn } from './utils';

export const Column = ({ width, height, color, opacity }: IColumn) => (
<Element data={createColumn(width, height, 20, color)} opacity={opacity} />
);

interface Props {
data: string;
opacity: number;
}

const Element = styled.div<Props>`
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-image: url(${({ data }) => data});
background-repeat: repeat;
opacity: ${({ opacity }) => opacity};
`;
10 changes: 10 additions & 0 deletions app/components/column/IColumn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Color } from '../../utils/Color';

export interface IColumn {
className?: string;
id: string;
color: Color;
width: number;
height: number;
opacity: number;
}
12 changes: 12 additions & 0 deletions app/components/column/factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as uuid from 'uuid/v1';
import { Color } from '../../utils/Color';
import { IColumn } from './IColumn';

export const factory = (id: string = uuid(), props = {}): IColumn => ({
id,
width: 100,
height: 100,
color: Color.RED,
opacity: 0.1,
...props
});
17 changes: 17 additions & 0 deletions app/components/column/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const createColumn = (
width: number,
height: number,
gap: number,
color: string
): string => {
const canvas: HTMLCanvasElement = document.createElement('canvas');
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;

canvas.width = width + gap;
canvas.height = height;

ctx.fillStyle = color;
ctx.fillRect(0, 0, width, height);

return canvas.toDataURL();
};
2 changes: 1 addition & 1 deletion app/components/guide/Guide.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ interface Props {
remove: () => void;
}

export default class Guide extends React.Component<IGuide & Props, State> {
export class Guide extends React.Component<IGuide & Props, State> {
private el: React.RefObject<HTMLDivElement> = React.createRef();

static getDerivedStateFromProps(nextProps, prevState) {
Expand Down
5 changes: 1 addition & 4 deletions app/components/onionImage/OnionImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@ interface Props {
remove: () => void;
}

export default class OnionImage extends React.Component<
IOnionImage & Props,
State
> {
export class OnionImage extends React.Component<IOnionImage & Props, State> {
private el: React.RefObject<HTMLDivElement> = React.createRef();
private image: React.RefObject<HTMLImageElement> = React.createRef();

Expand Down
2 changes: 1 addition & 1 deletion app/components/ruler/Ruler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ interface Props {
remove: () => void;
}

export default class Ruler extends React.Component<IRuler & Props, State> {
export class Ruler extends React.Component<IRuler & Props, State> {
private el: React.RefObject<HTMLDivElement> = React.createRef();
private ruler: React.RefObject<HTMLDivElement> = React.createRef();

Expand Down
1 change: 1 addition & 0 deletions app/components/toolbox/Tool.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum Tool {
COLUMN = 'column',
GUIDE = 'guide',
RULER = 'ruler',
ONION = 'onion',
Expand Down
15 changes: 13 additions & 2 deletions app/components/toolbox/Toolbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface Props {
x: number;
y: number;
isStuffVisible: boolean;
isColumnVisible: boolean;
isGridVisible: boolean;
toggleVisibility: () => void;
create: (tool: Tool) => void;
Expand Down Expand Up @@ -62,6 +63,7 @@ export class Toolbox extends React.Component<Props, State> {
render() {
const {
isStuffVisible,
isColumnVisible,
isGridVisible,
x,
y,
Expand All @@ -82,7 +84,10 @@ export class Toolbox extends React.Component<Props, State> {
title={`${isStuffVisible ? 'Hide' : 'Show'} all`}
onClick={() => toggleVisibility()}
>
<MiniToolboxIcon icon={isStuffVisible ? 'eye' : 'eye-off'} />
<MiniToolboxIcon
active={isStuffVisible}
icon={isStuffVisible ? 'eye' : 'eye-off'}
/>
</MiniToolboxItem>
<ToolSpace />
<MiniToolboxItem title="New guide" onClick={() => create(Tool.GUIDE)}>
Expand All @@ -101,7 +106,13 @@ export class Toolbox extends React.Component<Props, State> {
title={isGridVisible ? 'Hide grid' : 'Show grid'}
onClick={() => toggle(Tool.GRID)}
>
<MiniToolboxIcon icon="grid" />
<MiniToolboxIcon active={isGridVisible} icon="grid" />
</MiniToolboxItem>
<MiniToolboxItem
title={isColumnVisible ? 'Hide columns' : 'Show columns'}
onClick={() => toggle(Tool.COLUMN)}
>
<MiniToolboxIcon active={isColumnVisible} icon="pause" />
</MiniToolboxItem>
<ToolSpace />
<MiniToolboxItem title="Show help" onClick={toggleHelp}>
Expand Down
20 changes: 20 additions & 0 deletions app/reducers/columns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as R from 'ramda';
import { AnyAction } from 'redux';
import { ADD_COLUMN, REMOVE_COLUMN } from '../actions/columns';
import { IColumn } from '../components/column/IColumn';

const initialStore: IColumn[] = [];

export const columns = (
store = initialStore,
{ type, payload }: AnyAction
): IColumn[] => {
switch (type) {
case ADD_COLUMN:
return R.append(payload, store);
case REMOVE_COLUMN:
return R.reject(R.equals(payload), store);
}

return store;
};
4 changes: 4 additions & 0 deletions app/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import { IGrid } from '../components/grid/IGrid';
import { IGuide } from '../components/guide/IGuide';
import { IOnionImage } from '../components/onionImage/IOnionImage';
import { IRuler } from '../components/ruler/IRuler';
import { columns } from './columns';
import { grids } from './grids';
import { guides } from './guides';
import { onions } from './onions';
import { rulers } from './rulers';
import { tools, ToolsStore } from './tools';
import { help, HelpStore } from './help';
import { IColumn } from '../components/column/IColumn';

export interface AppStore {
columns: IColumn[];
grids: IGrid[];
guides: IGuide[];
onions: IOnionImage[];
Expand All @@ -20,6 +23,7 @@ export interface AppStore {
}

const rootReducer = combineReducers<AppStore>({
columns,
grids,
guides,
onions,
Expand Down

0 comments on commit efaf21a

Please sign in to comment.