@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.mjsexport const state = {  merge: 'gets merged into state',}export const actions = {  mergedActions: state => ({ ...state, merge: 'merged action executed' }),}

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>

the Menu module allows multiple props to be passed when instantiating the Menu

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)})

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'})

to define a submenu, simply define a .items array on the menu item

// assets/app.mjsexport default {  state: {    // ...state    menuName: [      {        to: '/example-page',        text: 'example page',        items: [          { to: '/example-page/#sub', text: 'example sub page' },      ] },    ],  },  // ... rest of app.mjs}

the link module allows you to link to things.

// in any page or module Viewexport 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 Viewexport 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"/>]

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