Add the appbar scrolling dropshadow
This commit is contained in:
parent
db4474cdab
commit
e4d5dcee4d
@ -1,7 +1,14 @@
|
|||||||
@import '../node_modules/semantic-ui-reset/reset.css';
|
@import '../node_modules/semantic-ui-reset/reset.css';
|
||||||
@import '../node_modules/semantic-ui-site/site.css';
|
@import '../node_modules/semantic-ui-site/site.css';
|
||||||
|
|
||||||
|
html {
|
||||||
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
import { prop, computed, bundle } from 'frptools';
|
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';
|
import { injectStyle, styled } from '../../services/style.js';
|
||||||
|
|
||||||
export function AppBarView(vm, params, key, opts) {
|
export function AppBarView(vm, params, key, opts) {
|
||||||
const title = prop(params.title);
|
const title = prop(params.title);
|
||||||
const renderButtons = prop(params.renderButtons || (() => []));
|
const renderButtons = prop(params.renderButtons || (() => []));
|
||||||
const hasBackButton = prop(false);
|
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) {
|
if (opts.appbar) {
|
||||||
throw new Error('Cannot have more than one AppBar.');
|
throw new Error('Cannot have more than one AppBar.');
|
||||||
@ -17,14 +21,16 @@ export function AppBarView(vm, params, key, opts) {
|
|||||||
title,
|
title,
|
||||||
renderButtons,
|
renderButtons,
|
||||||
hasBackButton,
|
hasBackButton,
|
||||||
showDropShadow
|
companionScrollTop
|
||||||
};
|
};
|
||||||
|
|
||||||
|
subscribeToRender(vm, [boxShadowStyle, renderButtons]);
|
||||||
|
|
||||||
return (vm, params) => {
|
return (vm, params) => {
|
||||||
const { title } = params;
|
const { title } = params;
|
||||||
return header(
|
return header(
|
||||||
{
|
{
|
||||||
css: { boxShadow: showDropShadow() ? '0px 0px 7px gray' : 'none' }
|
css: { boxShadow: boxShadowStyle() }
|
||||||
},
|
},
|
||||||
[el('div', { style: 'font-size: 20pt' }, title), headerRight(renderButtons()())]
|
[el('div', { style: 'font-size: 20pt' }, title), headerRight(renderButtons()())]
|
||||||
);
|
);
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import { Overlay } from './components/overlay.js';
|
|||||||
import { AppBarView } from './components/appbar.js';
|
import { AppBarView } from './components/appbar.js';
|
||||||
import { Icon } from './components/icon.js';
|
import { Icon } from './components/icon.js';
|
||||||
import { routeChanged } from '../services/router.js';
|
import { routeChanged } from '../services/router.js';
|
||||||
import { injectStyle } from '../services/style.js';
|
import { injectStyle, styled } from '../services/style.js';
|
||||||
|
|
||||||
export function GalleryView(vm) {
|
export function GalleryView(vm) {
|
||||||
let data = null;
|
let data = null;
|
||||||
@ -34,6 +34,10 @@ export function GalleryView(vm) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function handleContentScroll(evt) {
|
||||||
|
context.appbar.companionScrollTop(evt.target.scrollTop);
|
||||||
|
}
|
||||||
|
|
||||||
function renderWelcomePane() {
|
function renderWelcomePane() {
|
||||||
return [Overlay([el('h1', 'Hi')])];
|
return [Overlay([el('h1', 'Hi')])];
|
||||||
}
|
}
|
||||||
@ -60,9 +64,10 @@ export function GalleryView(vm) {
|
|||||||
'appbar',
|
'appbar',
|
||||||
context
|
context
|
||||||
),
|
),
|
||||||
el(
|
content(
|
||||||
'div',
|
{
|
||||||
{ class: fill },
|
onscroll: handleContentScroll
|
||||||
|
},
|
||||||
hasData() ? [vw(AllImagesView, {}, 'allImages', context)] : [renderWelcomePane()]
|
hasData() ? [vw(AllImagesView, {}, 'allImages', context)] : [renderWelcomePane()]
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
@ -89,8 +94,11 @@ export function GalleryView(vm) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const fill = injectStyle({
|
const FILL_STYLE = {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'column'
|
flexDirection: 'column'
|
||||||
});
|
};
|
||||||
|
const fill = injectStyle(FILL_STYLE);
|
||||||
|
|
||||||
|
const content = styled({ overflow: 'auto' }, FILL_STYLE);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import Styletron from 'styletron';
|
import Styletron from 'styletron';
|
||||||
import { injectStyle as _injectStyle } from 'styletron-utils';
|
import { injectStyle as _injectStyle } from 'styletron-utils';
|
||||||
import { defineElement } from '../utils/domvm.js';
|
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';
|
import { streamConfig } from '../utils/event.js';
|
||||||
|
|
||||||
const styletronSingleton = new Styletron();
|
const styletronSingleton = new Styletron();
|
||||||
@ -21,7 +21,7 @@ export function el(sig, ...attrsOrChildren) {
|
|||||||
attrs = attrsOrChildren[0];
|
attrs = attrsOrChildren[0];
|
||||||
children = attrsOrChildren.slice(1);
|
children = attrsOrChildren.slice(1);
|
||||||
if (isObject(attrs.css)) {
|
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();
|
attrs.class = `${className} ${attrs.class || ''}`.trim();
|
||||||
delete attrs.css;
|
delete attrs.css;
|
||||||
delete attrs.styles;
|
delete attrs.styles;
|
||||||
@ -44,19 +44,25 @@ export function el(sig, ...attrsOrChildren) {
|
|||||||
return defineElement(sig, attrs, children);
|
return defineElement(sig, attrs, children);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function styled(styles, tagName = 'div') {
|
export function styled(...styles) {
|
||||||
const className = injectStyle(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) => {
|
return (...props) => {
|
||||||
const attrIndex = props.length && isObject(props[0]) ? 0 : -1;
|
const attrIndex = props.length && isObject(props[0]) ? 0 : -1;
|
||||||
const attrs =
|
const attrs =
|
||||||
attrIndex === -1
|
attrIndex === -1
|
||||||
? { class: className }
|
? { 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)) {
|
if (isObject(attrs.css)) {
|
||||||
attrs.styles = styles;
|
attrs.class += ' ' + injectStyle(attrs.css);
|
||||||
attrs.class = props[0].class || '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const children = props.slice(attrIndex + 1);
|
const children = props.slice(attrIndex + 1);
|
||||||
|
|||||||
@ -15,3 +15,7 @@ export function pouchDocArrayComparator(a, b) {
|
|||||||
export function isObject(obj) {
|
export function isObject(obj) {
|
||||||
return typeof obj === 'object' && !Array.isArray(obj);
|
return typeof obj === 'object' && !Array.isArray(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isString(str) {
|
||||||
|
return typeof obj === 'string';
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user