Here is a fully functional basic SPA app with Juris, in plain Javascript.
You can tweak it here SPA-Juris
import b from 'bss'
b.css({ body: {maxWidth : '1024px', m: '0 auto', ff: 'Segoe UI', bc: '#131323', c: 'white', fw: 300, fs: '1.2rem' }, p:{c:'orange', mt: 8} , a: { mr: '1em', fw: 300, fs: '1.25rem', c: 'white' }, nav: { display: 'flex', jc: 'center', gap: '1rem', mt: '2rem', mb: '2rem' }, h1: { c: '#ff0000', fw: 300 } })
const HomePage = (props, context) => {
const { getState } = context;
return {
render: () => ({
div: {
className: () => b`p 3rem ; mt 2rem;border 1px solid #ddd`.class,
children: [
{
h1: {
text: () => getState('homeTitle')
}
},
{
p: {
text: 'Welcome to the reactive Home Page!'
}
}
]
}
})
};
};
const ContactPage = (props, context) => {
const { getState } = context;
return {
render: () => ({
div: {
className: () => b`p 3rem ; mt 2rem;border 1px solid #ddd`.class,
children: [
{
h1: {
text: () => getState('contactTitle')
}
},
{
p: {
text: 'Welcome to the reactive Contact Page!'
}
}
]
}
})
};
};
const AboutPage = (props, context) => {
const { getState } = context;
return {
render: () => ({
div: {
className: () => b`p 3rem ; mt 2rem;border 1px solid #ddd`.class,
children: [
{
h1: {
text: () => getState('aboutTitle')
}
},
{
p: {
text: 'Welcome to the reactive About Page!'
}
}
]
}
})
};
};
const NotFoundPage = () => ({
div: {
children: [
{
h1: {
text: () => 'Page not found'
}
}
]
}
});
const RouteRenderer = (props, context) => {
const { getState } = context;
return {
render: () => ({
div: {
children: () => {
const currentRoute = getState('router.currentRoute', '/');
if (props[currentRoute]) {
const match = props[currentRoute];
return Array.isArray(match) ? match : [match];
}
if (props.notFound) {
return Array.isArray(props.notFound) ? props.notFound : [props.notFound];
}
return [{ div: { text: '404 - Route not found' } }];
}
}
})
};
};
const juris = new Juris({
states: {
homeTitle: 'Home Page',
aboutTitle: 'About Page',
contactTitle: 'Contact Page'
},
components: {
HomePage,
ContactPage,
AboutPage,
NotFoundPage,
RouteRenderer
}
});
const App = {
div: {
style: () => b`p 32 ff sans-serif bgc #eaeaea`,
children: [
{
nav: {
children: [
{
a: {
text: '🏠 Home',
href: '#/',
style: () => b`m 0 12 c #007acc td none fw 500`
}
},
{
a: {
text: '📞 Contact',
href: '#/contact',
style: () => b`m 0 12 c #007acc td none fw 500`
}
},
{
a: {
text: 'ℹ️ About',
href: '#/about',
style: () => b`m 0 12 c #007acc td none fw 500`
}
}
]
}
},
{
RouteRenderer: {
'/': { HomePage: {} },
'/about': { AboutPage: {} },
'/contact': { ContactPage: {} },
notFound: { NotFoundPage: {} }
}
}
]
}
};
document.getElementById('app').append(juris.objectToHtml(App));
window.addEventListener('hashchange', () => {
juris.setState('router.currentRoute', location.hash.slice(1) || '/');
});
Top comments (0)