109 lines
2.4 KiB
JavaScript
109 lines
2.4 KiB
JavaScript
import { prop, computed, container, pick } from 'frptools';
|
|
|
|
import { Icon } from './icon.js';
|
|
import { router } from '../../services/router.js';
|
|
import { defineElement as el, subscribeToRender } from '../../utils/domvm.js';
|
|
import { injectStyle, styled } from '../../services/style.js';
|
|
import { CLICKABLE } from '../styles.js';
|
|
|
|
let seq = 0;
|
|
|
|
export function AppBarView(vm, params, key, opts) {
|
|
const stateStack = container([], arr => arr.length);
|
|
const companionScrollTop = prop(0);
|
|
|
|
const currentState = computed(stack => stack[0] || {}, [stateStack]);
|
|
const title = computed(pick('title', ''), [currentState]);
|
|
const renderActions = computed(pick('actions'), [currentState]);
|
|
const up = computed(pick('up'), [currentState]);
|
|
const upButton = computed(pick('name', 'arrow_left'), [up]);
|
|
const upAction = computed(
|
|
upState => (upState.onclick ? upState.onclick : [popState, upState.navigateTo]),
|
|
[up]
|
|
);
|
|
const stateStyle = computed(pick('style', {}), [currentState]);
|
|
|
|
const boxShadowStyle = computed(
|
|
t => (t === 0 ? 'none' : `0px ${Math.min(t / 10, 3)}px 3px rgba(0, 0, 0, .2)`),
|
|
[companionScrollTop]
|
|
);
|
|
|
|
const containerStyle = computed(
|
|
(boxShadow, style) => ({
|
|
css: Object.assign({ boxShadow }, style)
|
|
}),
|
|
[boxShadowStyle, stateStyle]
|
|
);
|
|
|
|
if (opts.appbar) {
|
|
throw new Error('Cannot have more than one AppBar.');
|
|
}
|
|
|
|
function pushState(newState) {
|
|
stateStack.unshift(Object.assign({ _seq: seq++ }, newState));
|
|
}
|
|
|
|
function popState(navigateTo) {
|
|
stateStack.shift();
|
|
if (navigateTo) {
|
|
router.goto(navigateTo);
|
|
}
|
|
}
|
|
|
|
opts.appbar = {
|
|
pushState,
|
|
popState,
|
|
companionScrollTop
|
|
};
|
|
|
|
subscribeToRender(vm, [containerStyle, renderActions, up, title]);
|
|
|
|
return (vm, params) => {
|
|
const _buttons = renderActions() || (() => {});
|
|
|
|
return appBarContainer(containerStyle(), [
|
|
up()
|
|
? upButtonContainer(
|
|
{
|
|
onclick: upAction()
|
|
},
|
|
[
|
|
Icon({
|
|
name: upButton(),
|
|
size: 0.75
|
|
})
|
|
]
|
|
)
|
|
: null,
|
|
titleContainer(title()),
|
|
headerRight(_buttons())
|
|
]);
|
|
};
|
|
}
|
|
|
|
const appBarContainer = styled({
|
|
justifyContent: 'space-between',
|
|
padding: '1em',
|
|
zIndex: 1000,
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
width: '100%'
|
|
});
|
|
|
|
const upButtonContainer = styled(
|
|
{
|
|
marginRight: '1em'
|
|
},
|
|
CLICKABLE
|
|
);
|
|
|
|
const headerRight = styled({
|
|
display: 'flex',
|
|
alignItems: 'center'
|
|
});
|
|
|
|
const titleContainer = styled({
|
|
fontSize: '20pt',
|
|
flex: 1
|
|
});
|