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

Commit

Permalink
feat: add project list dropdown to chrome
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexpeschel committed Dec 18, 2017
1 parent 54970fe commit 1017ddf
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 62 deletions.
19 changes: 14 additions & 5 deletions src/component/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { Page } from '../store/page';
import { PatternListContainer } from './container/pattern_list';
import PatternsPane from '../lsg/patterns/panes/patterns-pane';
import PreviewPane from '../lsg/patterns/panes/preview-pane';
import ProjectPane from '../lsg/patterns/panes/project-pane';
import { ProjectList } from './container/project_list';
import PropertyPane from '../lsg/patterns/panes/property-pane';
import { PropertyList } from './container/property_list';
Expand All @@ -33,6 +32,7 @@ class App extends React.Component<AppProps> {
private static PropertiesListID = 'propertieslist';

@MobX.observable protected activeTab: string = App.PatternListID;
@MobX.observable protected projectListVisible: boolean = false;
@MobX.computed
protected get isPatternListVisible(): boolean {
return Boolean(this.activeTab === App.PatternListID);
Expand All @@ -46,6 +46,7 @@ class App extends React.Component<AppProps> {
super(props);
this.handleTabNaviagtionClick = this.handleTabNaviagtionClick.bind(this);
this.handleMainWindowClick = this.handleMainWindowClick.bind(this);
this.handleChromeToggle = this.handleChromeToggle.bind(this);
}

private handleMainWindowClick(): void {
Expand All @@ -69,7 +70,13 @@ class App extends React.Component<AppProps> {

return (
<Layout directionVertical handleClick={this.handleMainWindowClick}>
<Chrome title={title} />
<Chrome
title={title}
handleClick={this.handleChromeToggle}
open={this.projectListVisible}
>
<ProjectList store={this.props.store} visible={this.projectListVisible} />
</Chrome>
<MainArea>
<SideBar directionVertical hasPaddings>
<ElementPane>
Expand All @@ -85,9 +92,6 @@ class App extends React.Component<AppProps> {
<PropertyPane>
<PropertyList store={this.props.store} />
</PropertyPane>
<ProjectPane>
<ProjectList store={this.props.store} />
</ProjectPane>
</SideBar>
<IconRegistry names={IconName} />
</MainArea>
Expand All @@ -100,6 +104,11 @@ class App extends React.Component<AppProps> {
protected handleTabNaviagtionClick(evt: React.MouseEvent<HTMLElement>, id: string): void {
this.activeTab = id;
}

@MobX.action
protected handleChromeToggle(evt: React.MouseEvent<HTMLElement>): void {
this.projectListVisible = !this.projectListVisible;
}
}

const store = new Store();
Expand Down
12 changes: 11 additions & 1 deletion src/component/container/chrome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,21 @@ import * as React from 'react';

export interface ChromeProps {
title: string;
handleClick?: React.MouseEventHandler<HTMLElement>;
open?: boolean;
}

@observer
export class Chrome extends React.Component<ChromeProps> {
public render(): JSX.Element {
return <ChromeComponent title={this.props.title} />;
return (
<ChromeComponent
handleClick={this.props.handleClick}
title={this.props.title}
open={this.props.open}
>
{this.props.children}
</ChromeComponent>
);
}
}
73 changes: 30 additions & 43 deletions src/component/container/project_list.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,50 @@
import List, { Label, Li, ListItemProps, Ul, Value } from '../../lsg/patterns/list';
import Dropdown from '../../lsg/patterns/dropdown';
import DropdownItem, {
DropdownItemLinkAttribute,
DropdownItemLinkAttributeItem
} from '../../lsg/patterns/dropdown-item';
import { IconName } from '../../lsg/patterns/icons';
import { observer } from 'mobx-react';
import { PageRef } from '../../store/project/page_ref';
import { Project } from '../../store/project';
import * as React from 'react';
import Space, { Size } from '../../lsg/patterns/space';
import { Store } from '../../store';

export interface ProjectListProps {
store: Store;
visible?: boolean;
}

@observer
export class ProjectList extends React.Component<ProjectListProps> {
public constructor(props: ProjectListProps) {
super(props);
}

public render(): JSX.Element {
const items: ListItemProps[] = this.props.store.getProjects().map((project: Project) => ({
label: 'Project',
value: project.getName(),
children: project.getPages().map((page: PageRef) => ({
label: 'Page',
value: page.getName(),
children: [],
onClick: (event: React.MouseEvent<HTMLElement>) => {
this.props.store.openPage(page.getId());
}
}))
}));

const list = this.createList(items);

return <List headline="Projects">{list}</List>;
this.handleProjectClick = this.handleProjectClick.bind(this);
}

public createList(items: ListItemProps[]): JSX.Element {
public render(): JSX.Element {
return (
<Space sizeLeft={Size.M}>
<Ul>
{items.map((props: ListItemProps, index: number) => {
const labelComponent = props.label ? <Label>{props.label}:</Label> : null;
const nextLevel = props.children ? this.createList(props.children) : null;

return (
<Li
handleDragStart={props.handleDragStart}
key={index}
active={props.active}
onClick={props.onClick}
>
{labelComponent}
<Value>{props.value}</Value>
{nextLevel}
</Li>
);
})}
</Ul>
</Space>
<Dropdown chrome visible={this.props.visible}>
{this.props.store.getProjects().map((project: Project, index) => (
<DropdownItem
name={project.getName()}
key={index}
handleClick={(e: React.MouseEvent<HTMLElement>) => {
e.preventDefault();
this.handleProjectClick(project.getId());
}}
>
<DropdownItemLinkAttribute>
<DropdownItemLinkAttributeItem>Edit</DropdownItemLinkAttributeItem>
<DropdownItemLinkAttributeItem>Delete</DropdownItemLinkAttributeItem>
</DropdownItemLinkAttribute>
</DropdownItem>
))}
<DropdownItem name="New project" icon={IconName.Robo} />
</Dropdown>
);
}
protected handleProjectClick(id: string): void {
this.props.store.openFirstPage(id);
}
}
53 changes: 43 additions & 10 deletions src/lsg/patterns/chrome/index.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
import { colors } from '../colors';
import { fonts } from '../fonts';
import { Icon, IconName, Size as IconSize } from '../icons';
import * as React from 'react';
import Space, { Size } from '../space';
import { getSpace, Size as SpaceSize } from '../space';
import styled from 'styled-components';

export interface ChromeProps {
title: string;
open?: boolean;
handleClick?: React.MouseEventHandler<HTMLElement>;
active?: boolean;
}

const StyledChrome = styled(Space).attrs({
size: Size.XS,
sizeLeft: Size.XXL * 3,
inside: true
})`
export interface ChromeTitleProps {
open?: boolean;
handleClick?: React.MouseEventHandler<HTMLElement>;
}

interface StyledChromeIconProps {
open?: boolean;
}

export interface StyledChromeDropDownItemProps {
active?: boolean;
}

const StyledChrome = styled.div`
box-sizing: border-box;
position: absolute;
top: 0;
display: flex;
width: 100%;
align-items: center;
font-family: ${fonts().NORMAL_FONT};
width: 100%;
height: 54px;
padding: ${getSpace(SpaceSize.XS)}px ${getSpace(SpaceSize.XXL) * 3}px;
font-family: ${fonts().NORMAL_FONT};
-webkit-app-region: drag;
-webkit-user-select: none;
user-select: none;
Expand All @@ -30,14 +45,32 @@ const StyledChromeTitle = styled.div`
align-items: center;
margin: 0 auto;
color: ${colors.grey36.toString()};
font-size: 15px;
font-size: 15px;
`;

const StyledChromeIcon = styled(Icon)`
margin-left: ${getSpace(SpaceSize.XS)}px;
fill: ${colors.grey36.toString()};
transition: transform 0.2s;
${(props: StyledChromeIconProps) => (props.open ? 'transform: rotate(90deg)' : '')};
`;

export default class Chrome extends React.Component<ChromeProps> {
public render(): JSX.Element {
const { title, handleClick } = this.props;

return (
<StyledChrome>
<StyledChromeTitle>{this.props.title}</StyledChromeTitle>
<StyledChromeTitle onClick={handleClick}>
{title}
<StyledChromeIcon
size={IconSize.XXS}
name={IconName.ArrowFill}
open={this.props.open}
/>
</StyledChromeTitle>
{this.props.children}
</StyledChrome>
);
}
Expand Down
4 changes: 1 addition & 3 deletions src/lsg/patterns/dropdown-item/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ export interface DropdownItemProps {
icon?: IconName;
handleClick?: React.MouseEventHandler<HTMLElement>;
}

export interface StyledDropdownItemLinkProps {
color?: Color;
handleClick?: React.MouseEventHandler<HTMLElement>;
}

const StyledDropdownItem = styled.div`
Expand Down Expand Up @@ -68,7 +66,7 @@ export default class DropdownItem extends React.Component<DropdownItemProps> {
public render(): JSX.Element {
return (
<StyledDropdownItem>
<StyledDropdownItemLink handleClick={this.props.handleClick}>
<StyledDropdownItemLink onClick={this.props.handleClick}>
{this.props.icon && (
<StyledDropdownItemIcon size={IconSize.XXS} name={this.props.icon} />
)}
Expand Down

0 comments on commit 1017ddf

Please sign in to comment.