diff --git a/packages/gallery/src/app.css b/packages/gallery/src/app.css index b8ef1f2..023aa9c 100644 --- a/packages/gallery/src/app.css +++ b/packages/gallery/src/app.css @@ -1,7 +1,14 @@ @import '../node_modules/semantic-ui-reset/reset.css'; @import '../node_modules/semantic-ui-site/site.css'; +html { + overflow: hidden; + height: 100%; +} + body { + height: 100%; + overflow: auto; display: flex; flex-direction: column; } diff --git a/packages/gallery/src/interface/components/appbar.js b/packages/gallery/src/interface/components/appbar.js index be786ee..29e215c 100644 --- a/packages/gallery/src/interface/components/appbar.js +++ b/packages/gallery/src/interface/components/appbar.js @@ -1,13 +1,17 @@ import { prop, computed, bundle } from 'frptools'; -import { defineElement as el } from '../../utils/domvm.js'; +import { defineElement as el, subscribeToRender } from '../../utils/domvm.js'; import { injectStyle, styled } from '../../services/style.js'; export function AppBarView(vm, params, key, opts) { const title = prop(params.title); const renderButtons = prop(params.renderButtons || (() => [])); const hasBackButton = prop(false); - const showDropShadow = prop(false); + const companionScrollTop = prop(0); + const boxShadowStyle = computed( + t => (t === 0 ? 'none' : `0px ${Math.min(t / 10, 3)}px 3px rgba(0, 0, 0, .2)`), + [companionScrollTop] + ); if (opts.appbar) { throw new Error('Cannot have more than one AppBar.'); @@ -17,14 +21,16 @@ export function AppBarView(vm, params, key, opts) { title, renderButtons, hasBackButton, - showDropShadow + companionScrollTop }; + subscribeToRender(vm, [boxShadowStyle, renderButtons]); + return (vm, params) => { const { title } = params; return header( { - css: { boxShadow: showDropShadow() ? '0px 0px 7px gray' : 'none' } + css: { boxShadow: boxShadowStyle() } }, [el('div', { style: 'font-size: 20pt' }, title), headerRight(renderButtons()())] ); diff --git a/packages/gallery/src/interface/gallery.js b/packages/gallery/src/interface/gallery.js index 4cca059..fc24cde 100644 --- a/packages/gallery/src/interface/gallery.js +++ b/packages/gallery/src/interface/gallery.js @@ -10,7 +10,7 @@ import { Overlay } from './components/overlay.js'; import { AppBarView } from './components/appbar.js'; import { Icon } from './components/icon.js'; import { routeChanged } from '../services/router.js'; -import { injectStyle } from '../services/style.js'; +import { injectStyle, styled } from '../services/style.js'; export function GalleryView(vm) { let data = null; @@ -34,6 +34,10 @@ export function GalleryView(vm) { } }); + function handleContentScroll(evt) { + context.appbar.companionScrollTop(evt.target.scrollTop); + } + function renderWelcomePane() { return [Overlay([el('h1', 'Hi')])]; } @@ -60,9 +64,10 @@ export function GalleryView(vm) { 'appbar', context ), - el( - 'div', - { class: fill }, + content( + { + onscroll: handleContentScroll + }, hasData() ? [vw(AllImagesView, {}, 'allImages', context)] : [renderWelcomePane()] ) ]; @@ -89,8 +94,11 @@ export function GalleryView(vm) { }; } -const fill = injectStyle({ +const FILL_STYLE = { display: 'flex', flex: 1, flexDirection: 'column' -}); +}; +const fill = injectStyle(FILL_STYLE); + +const content = styled({ overflow: 'auto' }, FILL_STYLE); diff --git a/packages/gallery/src/services/style.js b/packages/gallery/src/services/style.js index 2019945..57ceb27 100644 --- a/packages/gallery/src/services/style.js +++ b/packages/gallery/src/services/style.js @@ -1,7 +1,7 @@ import Styletron from 'styletron'; import { injectStyle as _injectStyle } from 'styletron-utils'; import { defineElement } from '../utils/domvm.js'; -import { isObject } from '../utils/comparators.js'; +import { isObject, isString } from '../utils/comparators.js'; import { streamConfig } from '../utils/event.js'; const styletronSingleton = new Styletron(); @@ -21,7 +21,7 @@ export function el(sig, ...attrsOrChildren) { attrs = attrsOrChildren[0]; children = attrsOrChildren.slice(1); if (isObject(attrs.css)) { - const className = injectStyle(Object.assign(attrs.css, attrs.styles || {})); + const className = injectStyle(Object.assign({}, attrs.css, attrs.styles || {})); attrs.class = `${className} ${attrs.class || ''}`.trim(); delete attrs.css; delete attrs.styles; @@ -44,19 +44,25 @@ export function el(sig, ...attrsOrChildren) { return defineElement(sig, attrs, children); } -export function styled(styles, tagName = 'div') { - const className = injectStyle(styles); +export function styled(...styles) { + let className; + let tagName = 'div'; + if (styles.length > 1 && isString(styles[0])) { + tagName = styles[0]; + className = injectStyle(...styles.slice(1)); + } else { + className = injectStyle(...styles); + } return (...props) => { const attrIndex = props.length && isObject(props[0]) ? 0 : -1; const attrs = attrIndex === -1 ? { class: className } - : Object.assign({}, props[0], { className: `${className} ${props[0].className || ''}`.trim() }); + : Object.assign({}, props[0], { class: `${className} ${props[0].class || ''}`.trim() }); if (isObject(attrs.css)) { - attrs.styles = styles; - attrs.class = props[0].class || ''; + attrs.class += ' ' + injectStyle(attrs.css); } const children = props.slice(attrIndex + 1); diff --git a/packages/gallery/src/utils/comparators.js b/packages/gallery/src/utils/comparators.js index 29956b3..7a97155 100644 --- a/packages/gallery/src/utils/comparators.js +++ b/packages/gallery/src/utils/comparators.js @@ -15,3 +15,7 @@ export function pouchDocArrayComparator(a, b) { export function isObject(obj) { return typeof obj === 'object' && !Array.isArray(obj); } + +export function isString(str) { + return typeof obj === 'string'; +}