@magic
@magic-modules
preinstalled
magic has some preinstalled modules that will be used in most pages.
app
this is the main app module. it has magically inherited properties and all of it is customizable.
to add actions/state/style to the app you can just create an /assets/app.mjs file. the contents of this file get deep .merged into the app
// /src/app.mjs
export const state = {
merge: 'gets merged into state',
}
export const actions = {
mergedActions: state => ({ ...state, merge: 'merged action executed' }),
}
menu
the Menu module provides... menus.
export const View = state => {
const items = [
{ to: '/', text: 'example page' },
{ to: 'https://example.com', text: 'example.com' },
{ to: 'https://example.com', nofollow: true, noreferrer: true, target: 'utopia', text: 'nofollow and noref" },
]
return Menu({ items, collapse: false })
}
// output:
<nav class="Menu">
<ul>
<li>
<a onclick="actions.go" href="/">example page
</li>
<li>
<a href="https://example.com" target="_blank" rel="noopener">example.com
</li>
<li>
<a href="https://example.com" target="utopia" rel="noopener nofollow noreferrer">nofollow and noref
</li>
</ul>
</nav>
Menu props
the Menu module allows multiple props to be passed when instantiating the Menu
props.collapse
by default, the menu will only show submenu items if their parent link is active. to force submenu items to show at all times, just pass a collapse: false prop
Menu({
// if false, menu will always show all submenu items
collapse: false, // (default: true)
})
Menu.Item props
every MenuItem accepts the same props as a link does. additionally a MenuItem accepts an items prop with sub menu items.
const menuItem = ({
to: '/url',
text: 'link text',
items: [MenuItems],
noreferrer: true, // set rel='noreferrer'
nofollow: true, // set rel='nofollow'
})
sub menus
to define a submenu, simply define a .items array on the menu item
// assets/app.mjs
export default {
state: {
// ...state
menuName: [
{
to: '/example-page',
text: 'example page',
items: [
{ to: '/example-page/#sub', text: 'example sub page' },
] },
],
},
// ... rest of app.mjs
}
link
the link module allows you to link to things.
// in any page or module View
export default () => [
Link({ to: '/', text: 'page' }),
// output: <a href="/" onclick="actions.go">page
Link({ to: 'https://example.com', text: 'page' }),
// output: <a href="https://example.com" target="_blank" rel="noopener">page
Link({ to: '/', text: 'page', nofollow: true, noreferrer: true }),
// output: <a href="https://example.com" target="_blank" rel="nofollow noreferrer noopener">page
// you can also use children syntax instead of the text prop:
Link({ to: '/' }, 'home'),
// Link also supports # hash links
Link({ to: '/#hash' }, 'home with hash'),
]
img
the img module adds some sane default values to your images.
// in any page or module View
export default () => [
Img('/image.png'),
// output: <img src="/image.png" alt="" role="presentation"/>
Img({ src: '/image.png' }),
// output: <img src="/image.png" alt="" role="presentation"/>
Img({ src: '/image.png', alt: 'image description' }),
// output: <img src="/image.png" alt="image description" />
Img({ src: '/image.png', title: 'image title', }),
// output: <img src="/image.png" title="image title" alt="image title"/>
Img({ src: '/image.png', title: 'image title', alt: 'image alt' }),
// output: <img src="/image.png" title="image title" alt="image alt"/>
]
footer
the footer module contains a small info text and a link to the magic github repository.
to overwrite this behaviour, just place a Footer.mjs file in your assets and require it in /assets/index.mjs.
// /assets/Footer.mjs:
const Footer = () =>
footer({ class: 'main' }, [
div({ class: 'wrapper' }, [
'made with a few bits of ',
Link({ href: 'https://github.com/magic/core', target: '_blank', rel: 'noopener' }, 'magic'),
]),
])
Footer.style: {
'footer.main': {
position: 'relative',
textAlign: 'center',
padding: '5em 0 .5em',
},
}
export default Footer