cloude.logged-mobile · sandbox

Config file

The package's live config/logged-mobile.php — the single source the shell renders from. This reads the file fresh on every load, so edit it and refresh to see the change.

<?php

/*
|--------------------------------------------------------------------------
| Logged Mobile · navigation shell configuration
|--------------------------------------------------------------------------
|
| Everything the shell renders is driven from this file — there are no
| hard-coded application specifics. Publish it with:
|
|     php artisan vendor:publish --tag=logged-mobile-config
|
| then reshape the nav, theme and hub to suit the host app.
|
*/

return [

    /*
    | Theme · emitted as CSS custom properties on the shell root. Override any
    | value to reskin the entire chrome; every colour is referenced via var().
    |
    | `direction` is which edge the nav docks to: 'bottom' (default), 'top',
    | 'left' or 'right' — 'left'/'right' render as a vertical rail. It can be
    | changed live by dispatching a `logged-mobile:set-direction` window event
    | (see the README). An unrecognised value falls back to 'bottom'.
    */
    'theme' => [
        'bg'        => '#1E1F22',
        'surface'   => '#26272B',
        'line'      => '#36373B',
        'line2'     => '#4A4B50',
        'chip'      => '#303135',
        'ink'       => '#F0EDE5',
        'ink2'      => '#B8B5AC',
        'muted'     => '#7A7872',
        'accent'    => '#C7593A',
        'on-accent' => '#FFFFFF',
        'radius'    => '1rem',
        'direction' => 'bottom',
    ],

    /*
    | Bottom navigation · a single ordered list; items render along the bar in
    | array order. A regular item carries a path-only `url` (a leaf), an
    | `items` array (a parent, with an optional `cols` for its sub-nav grid),
    | or an `event` to $dispatch on tap instead of navigating.
    | An item with 'type' => 'fab' renders as a round button (it always
    | dispatches its `event`) — put it anywhere in the list, as many as you
    | like, including inside a sub-nav's `items`. A fab may set `shape`:
    | 'circle' (default), 'rounded-square' or 'square'.
    | `icon` is either a key from `icon_types` below, a raw SVG path `d`
    | string, or an image — ['type' => 'image', 'src' => '…'] — which renders
    | as an <img> (on a fab the image fills the button, e.g. a profile photo).
    | A leaf `url` may include a #hash so a hash-routed view is distinguished
    | from its hash-less sibling. A sub-item may itself carry `items`, nesting
    | to any depth — the sub-nav drills into them with a Back row.
    |
    | Any item (here, in sub-navs and in the hub) may carry a `condition` — a
    | bool or a callable. A falsy condition hides the item; an absent one means
    | shown. A parent whose children are all hidden is dropped. Callable
    | conditions evaluate per render, so do not run `config:cache` with them.
    */
    'nav' => [
        [
            // A fab whose `icon` is an image · the avatar fills the
            // rounded-square button. Its `event` is `logged-mobile:open-hub`,
            // which the shell listens for — so this photo opens the "You" hub.
            'key' => 'me', 'label' => 'You', 'type' => 'fab',
            'shape' => 'rounded-square',
            'event' => 'logged-mobile:open-hub',
            'icon' => ['type' => 'image', 'src' => 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHJlY3Qgd2lkdGg9IjQwIiBoZWlnaHQ9IjQwIiBmaWxsPSIjM0M2RTcxIi8+PGNpcmNsZSBjeD0iMjAiIGN5PSIxNS41IiByPSI3IiBmaWxsPSIjRjBFREU1Ii8+PHBhdGggZD0iTTUuNSAzOGMwLTguNiA2LjUtMTMgMTQuNS0xM3MxNC41IDQuNCAxNC41IDEzeiIgZmlsbD0iI0YwRURFNSIvPjwvc3ZnPg=='],
        ],
        [
            'key' => 'home', 'label' => 'Home',
            'icon' => 'M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25',
            'url' => '/',
        ],
        [
            'key' => 'library', 'label' => 'Library',
            'icon' => 'M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25',
            'cols' => 4,
            'items' => [
                ['key' => 'recent',  'label' => 'Recent',  'icon' => 'M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z', 'url' => '/recent'],
                // A sub-item may nest its own `items`, to any depth · the
                // sub-nav drills into them with a Back row.
                ['key' => 'saved', 'label' => 'Saved', 'icon' => 'M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0111.186 0z', 'items' => [
                    ['key' => 'photos', 'label' => 'Photos', 'icon' => 'camera', 'url' => '/photos'],
                    ['key' => 'albums', 'label' => 'Albums', 'icon' => 'folder', 'items' => [
                        ['key' => 'album-2024', 'label' => '2024', 'icon' => 'folder', 'url' => '/albums/2024'],
                        ['key' => 'album-2023', 'label' => '2023', 'icon' => 'folder', 'url' => '/albums/2023'],
                    ]],
                ]],
                ['key' => 'tags',    'label' => 'Tags',    'icon' => 'M9.568 3H5.25A2.25 2.25 0 003 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 005.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 009.568 3z', 'url' => '/tags'],
                // A fab inside a sub-nav · `shape` makes it a rounded square.
                ['key' => 'lib-new', 'label' => 'New', 'type' => 'fab', 'shape' => 'rounded-square', 'icon' => 'compose', 'event' => 'logged-mobile:library-new'],
            ],
        ],
        [
            // A fab item · `icon` is a preset key here, `event` is dispatched
            // on tap. Move it earlier in the list to move it along the bar.
            'key' => 'create', 'label' => 'Create', 'type' => 'fab',
            'icon' => 'plus', 'event' => 'logged-mobile:create',
        ],
    ],

    /*
    | Icon presets · any item's `icon` (a nav item, a fab, a sub-nav item, a
    | hub row) may be one of these keys instead of a raw SVG path `d` string.
    | Add your own to grow the set.
    */
    'icon_types' => [
        'plus'       => 'M12 4.5v15m7.5-7.5h-15',
        'search'     => 'M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z',
        'pencil'     => 'M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.862 4.487z',
        'compose'    => 'M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10',
        'camera'     => 'M6.827 6.175A2.31 2.31 0 015.186 7.23c-.38.054-.757.112-1.134.175C2.999 7.58 2.25 8.507 2.25 9.574V18a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9.574c0-1.067-.75-1.994-1.802-2.169a47.865 47.865 0 00-1.134-.175 2.31 2.31 0 01-1.64-1.055l-.822-1.316a2.192 2.192 0 00-1.736-1.039 48.774 48.774 0 00-5.232 0 2.192 2.192 0 00-1.736 1.039l-.821 1.316zM16.5 12.75a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0zM18.75 10.5h.008v.008h-.008V10.5z',
        'microphone' => 'M12 18.75a6 6 0 006-6v-1.5m-6 7.5a6 6 0 01-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 01-3-3V4.5a3 3 0 116 0v8.25a3 3 0 01-3 3z',
        'folder'     => 'M2.25 12.75V12A2.25 2.25 0 014.5 9.75h15A2.25 2.25 0 0121.75 12v.75m-8.69-6.44l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z',
    ],

    /*
    | Realtime connection indicator · an optional pill that straddles the bar
    | top. Off by default. The host feeds it state by dispatching a
    | `logged-mobile:socket` window event with { state: 'connected' |
    | 'connecting' | 'disconnected' | … } from its Echo / Pusher / WebSocket
    | lifecycle. Any state other than 'connected' shows as amber.
    */
    'socket' => [
        'show'   => false,
        'labels' => [
            'connected'  => 'Live',
            'connecting' => 'Connecting',
            'offline'    => 'Offline',
        ],
    ],

    /*
    | "You" hub · a swipe-down-to-dismiss sheet opened by the hub trigger pill,
    | or by dispatching the `logged-mobile:open-hub` window event from any host
    | element. `items` are its menu rows; `finder` enables the rainbow-glow
    | "find a feature" tutorial that lights a route through the nav.
    */
    'hub' => [
        'enabled' => true,
        'title'   => 'You',
        'trigger' => [
            'show'  => true,
            'label' => 'You',
            'icon'  => 'M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z',
        ],
        'items' => [
            ['key' => 'profile',  'label' => 'Profile',  'icon' => 'M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z', 'url' => '/profile'],
            ['key' => 'settings', 'label' => 'Settings', 'icon' => 'M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a6.759 6.759 0 010 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.759 6.759 0 010-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.281z M15 12a3 3 0 11-6 0 3 3 0 016 0z', 'url' => '/settings'],
        ],
        'finder'       => true,
        'finder_label' => 'Find a feature',
    ],

    /*
    | Toasts · a floating stack. Any host code (Livewire, Echo, plain JS) can
    | raise one by dispatching a `toast` browser event with detail
    | { message, level?, url?, sentAt? }. A toast carrying a `url` is tappable
    | and lingers longer.
    */
    'toasts' => [
        'enabled'         => true,
        'duration'        => 6000,
        'duration_linked' => 12000,
        'position'        => 'top-right',
    ],

];
Nav
Follow the glow to

You

Profile Settings

Pick a destination: the nav lights up the route so you learn where it lives.