Skip to content

Commit

Permalink
feat(component): Start of Drawer component
Browse files Browse the repository at this point in the history
  • Loading branch information
arlair committed Apr 22, 2016
1 parent 532aecd commit be02a5b
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 4 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"ghooks": "1.0.3",
"mocha": "^2.4.5",
"semantic-release": "^4.3.5",
"typescript": "^1.8.7",
"typescript": "^1.8.10",
"typings": "0.7.9"
},
"keywords": [
Expand Down
128 changes: 128 additions & 0 deletions src/drawer/Drawer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { Observable as $, Subject } from 'rx';
const { h, aside } = require('cycle-snabbdom');
const dialogPolyfill = require('dialog-polyfill/dialog-polyfill.js');
import * as classNames from 'classnames';
const style = require('./style');
//const style = require('react-toolbox/lib/drawer/style');
import { componentFactory } from '../helpers/componentFactory';
import { CycleDomComponent, CycleComponent, CycleUiComponentProps }
from '../helpers/cycleDomInterfaces';

export interface DrawerProps extends CycleUiComponentProps {
active?: boolean;
// TODO Enum? oneOf(['left', 'right'])
type?: string;
}

export const DrawerDefaultProps: DrawerProps = {
isolate: true,
className: '',
active: false,
type: 'left',
};

export function Drawer(sources: any, props?: DrawerProps, children?: CycleComponent[]):
CycleDomComponent;
export function Drawer(sources: any, children?: CycleComponent[]): CycleDomComponent;

export function Drawer(sources: any, propsOrChildren: any, children?: any) {
return componentFactory<DrawerProps>(DrawerFactory, DrawerDefaultProps,
sources, propsOrChildren, children);
}

export function DrawerFactory(sources: any, props$: $<DrawerProps>,
children?: CycleComponent[]): CycleDomComponent {

let closeEvent$: any = new Subject();

let className: string;
props$.map( (props) => {
className = classNames([ style.root, style[props.type] ], {
[style.active]: props.active
}, props.className);
});

// const drawerClose$ = sources.DOM.select(`.${className}`).events('close').
// startWith(false).
// map((x: any) => false).
// do((x: any) => console.log('mydrawerClose$: ' + x));
//
// const drawerCancel$ = sources.DOM.select('.drawer').events('cancel').map(() => false).
// startWith(false).
// do((x: any) => console.log('drawerCancel: ' + x));

//const vtree$ = $.combineLatest(props$, drawerClose$, (props, drawerClose) => {
const vtree$ = props$.map( (props) => {
console.log('DOM');
const className = classNames([ style.root, style[props.type] ], {
[style.active]: props.active
}, props.className);

// const isOpen$ = $.merge(
// props.active,
// sources.DOM.select(`.${className}`).events('close').map(() => false),
// ).startWith(false)

const insert = (vnode: any) => {
console.log('insert hook');
const dialog: any = document.querySelector('dialog');
dialogPolyfill.registerDialog(dialog);
if (props.active) {
console.log('showing modal');
dialog.showModal();
dialog.oncancel = (event: any) => {
console.log('cancel');
};

dialog.addEventListener('close', (event: any) => {
console.log('theonclose');
closeEvent$.onNext(false);
});

// closeEvent$ = (<any>$).fromEvent(dialog, 'close').
// startWith(false);
dialog.onclick = (event: any) => {
const rect = dialog.getBoundingClientRect();
const isInDialog = (rect.top <= event.clientY && event.clientY <= rect.top + rect.height
&& rect.left <= event.clientX && event.clientX <= rect.left + rect.width);
if (!isInDialog) {
console.log('clicked outside dialog and about to close');
dialog.close();
}
};
// const backdrop: any = document.querySelector('.backdrop');
// console.log(backdrop);
// if (backdrop != null) {
// console.log('adding backdrop listener');
// backdrop.onclick = () => {
// console.log('click on backdrop');
// dialog.close();
// };
// }
} else {
const overlay: any = document.querySelector('._dialog_overlay');
if (overlay != null) {
console.log('removing dialog overlay');
overlay.parentNode.removeChild(overlay);
}
}
};

return (
// Overlay( { active: props.active }, [
// TODO only render when required: props.active &&, but errors if nothing is returned
h('dialog', {hook: {insert}, props: { className },
attrs: { 'data-cycle-ui': 'drawer' } }, [
aside( { props: { className: style.content } },
children
),
])
// ]).DOM
);
});

return {
DOM: vtree$,
closeEvent$
};
}
1 change: 1 addition & 0 deletions src/drawer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Drawer } from './Drawer';
30 changes: 30 additions & 0 deletions src/drawer/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@import "../../node_modules/react-toolbox/lib/base";
@import "../../node_modules/react-toolbox/lib/drawer/config";
@import "../../node_modules/react-toolbox/lib/drawer/style";
//@import "../../node_modules/dialog-polyfill/dialog-polyfill.css";

dialog[open] {
display: block;
position: fixed;
z-index: 10;
}

dialog + :global(.backdrop) {
position: fixed;
top: 0; right: 0; bottom: 0; left: 0;
background: rgba(0,0,0,0.1);
}

/* for small devices, modal dialogs go full-screen */
@media screen and (max-width: 540px) {
dialog[_polyfill_modal] { /* TODO: implement */
top: 0;
width: auto;
margin: 1em;
}
}

:global(._dialog_overlay) {
position: fixed;
top: 0; right: 0; bottom: 0; left: 0;
}
8 changes: 6 additions & 2 deletions src/helpers/componentFactory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const isolate = require('@cycle/isolate');
const isolateLocal = require('@cycle/isolate');
import { Observable } from 'rx';
import { getComponentParams } from './componentParams';
import { CycleUiComponentProps, CycleComponent } from './cycleDomInterfaces';
Expand All @@ -9,7 +9,11 @@ export function componentFactory<T extends CycleUiComponentProps>(factory: any,
const params = getComponentParams<T>(defaults, propsOrChildren, children);

if (params.props.isolate) {
factory = isolate(factory);
// if (typeof sources === 'undefined') {
factory = isolateLocal(factory);
// } else {
// factory = sources.isolate(factory);
// }
}

const props$ = Observable.just(params.props);
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export { Button, ButtonFactory } from './button/index';
export { Card, CardTitle, CardText, CardActions } from './card/index';
export { Dialog } from './dialog/index';
export { Drawer } from './drawer/index';
export { Input } from './input/index';
export { RadioButton, RadioGroup } from './radio/index';
export { Overlay } from './overlay/index';
9 changes: 8 additions & 1 deletion src/overlay/Overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import * as classNames from 'classnames';
const style = require('react-toolbox/lib/overlay/style');
import { componentFactory } from '../helpers/componentFactory';
import { CycleDomComponent, CycleUiComponentProps } from '../helpers/cycleDomInterfaces';
const { concat } = require('lodash');

export interface OverlayProps extends CycleUiComponentProps {
active?: boolean;
Expand Down Expand Up @@ -41,6 +40,14 @@ export function OverlayFactory(props$: $<OverlayProps>,
children
)
]);
// return (
// h('dialog', {hook: {insert}, props: { className } }, [
// div( { props: { className } }, [
// div( { props: { className: style.overlay } },
// children
// )
// ]);

});

return {
Expand Down

0 comments on commit be02a5b

Please sign in to comment.