@tanglemedia/svelte-starter-layout
v2.2.0
Published
App layout components and shell components for use in svelte websites
Downloads
164
Readme
@tanglemedia/svelte-starter-layout
The Layout package is responsible for the main layout of your app after the user is authorized, but it also contains components responsible for style settings adn functionalities.
Most of the componet from the Layout packages behave as wrappers, that is, are components that have on them so you can pass it what you actually want the component to display, and it will display that in a nicely way.
Some of the componets present on the Layout package are also present on SkeletonUI package, and if you want more in depth analisys of those components you can check it out at their documentation. Those components are AppBar, AppRail, AppRailAnchor, AppRailTile, AppShell, TabGroup, TabAnchor. All these components are present in the Layout package, but they behave the same way as the ones in SkeletonUI.
Demo
On this section we are going to display how you can use some of the components that the Layout package provides on your svelte app.
LayoutSettings
The LayoutSettings is responsible to read some configurations of your app.yml config file, like:
- app.viewport
- app.seo.title
- app.settings.background.primary_color
- app.settings.background.secondary_color
- app.settings.text.primary_color
- app.settings.text.secondary_color After it gets the values of all those configurations it runs a function that calculates your project colors and set in your localStorage the colors:
localStorage.setItem('--settings-primary-color', primaryColor);
localStorage.setItem('--settings-secondary-color', secondaryColor);
localStorage.setItem('--settings-text-primary-color', textPrimaryColor);
localStorage.setItem('--settings-text-secondary-color', textSecondaryColor);
localStorage.setItem('--settings-text-contrast-primary-color', textContrastPrimary);
localStorage.setItem('--settings-text-contrast-secondary-color', textContrastSecondary);
customStyles = `--settings-primary-color: ${primaryColor}; --settings-secondary-color: ${secondaryColor};
--settings-text-primary-color: ${textPrimaryColor}; --settings-text-secondary-color: ${textSecondaryColor};
--settings-text-contrast-primary-color: ${textContrastPrimary}; --settings-text-contrast-secondary-color: ${textContrastSecondary}`;
And this is how you would use it, it would be in your first layout of your app.
<script lang='ts'>
import '$lib/styles/main.css';
import { ConfigProvider } from '@tanglemedia/svelte-starter-core';
import { QueryClientProvider } from '@tanstack/svelte-query';
import { Toaster } from 'svelte-french-toast';
import { LayoutSettings } from '@tanglemedia/svelte-starter-layout';
</script>
<Toaster />
<QueryClientProvider >
<ConfigProvider configFactory={provideConfig()}>
<LayoutSettings>
<slot />
</LayoutSettings>
</ConfigProvider>
</QueryClientProvider>
AppLayout
This is the AppLayout component from the @tanglemedia/svelte-starter-layout package, The AppLayout component is probably one of the most complex components in the @tanglemedia libraries.
Its main goal is to display a layout that will be followed on your entire (app) group route. It can change from a basic layout to a mobile layout if you pass the right props, but in all layouts, it has a place to display what page you are, a navigation place, and a slot place for you to actually display the content of a certain page.
<AppLayout sidebarExtraClass="pt-5" footerExtraClass="h-12 variant-filled-primary" subNavBarPageDescription={subnavbarDescription} subNavBar={true} backUrl={() => {goSomeWhereBack()}} subNavBarBackgroundImage={backgroundImage} display={"mobile"} appLogoImage={logo} headerImageClass={`w-24 ${sidebarCropped ? 'mt-2 md:w-20 md:mx-0' : 'md:w-32 md:mx-10'}`} on:sidebar={(e) => {sidebarCropped = e.detail;}}>
<ProfileButton {userAvatar} userEmail={user?.email} userName={`${user?.first_name} ${user?.last_name}`} profileLink={'/profile'} slot="ProfileButton" buttonIconClasses={'text-black'} onSuccess={async () => {
await logout();
}}/>
<div slot="content" class="xl:mt-3 px-5 md:px-0">
<PageTransition url={data.url}>
<slot />
</PageTransition>
</div>
</AppLayout>
Breaking Changes
Migrating from 0.0.24 to 1.0.0
On this update we redesigned completely the way you add the component yo your +layout.svelte page, we now have three new components:
- AppHeader
- AppSidebar
- AppFooter
As well as new stores:
- subNavbarStore
- breadcrumbStore
- drawerStore
- sidebarStore
First let's talk about the redesign of the layout.yml file as well. This is how the new layout.yml file should look like:
display:
# We now only have TWO display modes: mobile, and desktop.
mode: mobile
# We also separated the settings into GLOBAL, MOBILE, and DESKTOP. Although still most of the configuration are global
# Global settings
header:
#enabled is a new value, and it is used on the new AppLayout component, to either display the header or not.
enabled: true
# These settings are NOT inside a display object anymore.
profileButton: true
subNavbar: true
logoHref: '/dashboard'
userProfile:
links:
- name: Profile
href: /profile
- name: Change Password
href: /profile?tab=change_password
sidebar:
#enabled is a new value, and it is used on the new AppLayout component, to either display the sidebar or not.
enabled: true
# These settings are NOT inside a display object anymore.
position: left
offCanvas: true
# These configurations are untouched, but many people asked why they are empty (bottom, and buttons).
# They are empty because they are automatically set with the primary and secondary colours when you set the LayoutSettings components, so these are more like OVERWRITES for you primary and secondary colours of you sidebar menu.
bottom:
backgroundColor:
activeBackgroundColor:
iconColor:
iconActiveColor:
buttons:
mode: horizontal
backgroundColor:
activeBackgroundColor:
textColor:
activeTextColor:
# Mobile specific settings
# Because the footer section is only visible on mobile display modes, then the settings for the footer are inside the mobile object.
mobile:
footer:
#enabled is a new value, and it is used on the new AppLayout component, to either display the footer or not.
enabled: true
showTitle: false
desktop:
Now that you know about the updates on the layout.yml file, let's take a look at the changes on the way you set you layout.
Previously you would set the layout like this:
<AppLayout sidebarExtraClass="pt-5" footerExtraClass="h-12 variant-filled-primary" subNavBarPageDescription={subnavbarDescription} subNavBar={true} backUrl={() => {goSomeWhereBack()}} subNavBarBackgroundImage={backgroundImage} display={"mobile"} appLogoImage={logo} headerImageClass={`w-24 ${sidebarCropped ? 'mt-2 md:w-20 md:mx-0' : 'md:w-32 md:mx-10'}`} on:sidebar={(e) => {sidebarCropped = e.detail;}}>
<ProfileButton {userAvatar} userEmail={user?.email} userName={`${user?.first_name} ${user?.last_name}`} profileLink={'/profile'} slot="ProfileButton" buttonIconClasses={'text-black'} onSuccess={async () => {
await logout();
}}/>
<div slot="content" class="xl:mt-3 px-5 md:px-0">
<PageTransition url={data.url}>
<slot />
</PageTransition>
</div>
</AppLayout>
Now you could set it like this:
<AppLayout>
<AppHeader
slot="header"
subNavbarBackgroundImage={backgroundImage}
{logo}
logoClass="md:h-10"
autoSetBreadcrumbs={false}
>
<ProfileButton
slot="ProfileButton"
{avatar}
email={user?.email}
name={`${user?.first_name} ${user?.last_name}`}
profileLink={'/profile'}
iconHexColor="#fff"
buttonIconClasses={'text-white'}
onSuccess={async () => {
await logout();
}}
/>
</AppHeader>
<AppSidebar slot="sidebar" />
<AppFooter slot="footer" />
<div>
<slot />
</div>
</AppLayout>
The new way we break down the AppLayout into other components, to make it easier to understand what each component does, as well as make the logic behind the components way easier, and last but not the least it makes the naming of variables easier and less confusing like it was on the previous version where everything was in one component.
Finally let's take a look at the new stores:
- SubnavbarStore: This store makes you able to manually set the value of the subnavbar title, and description. Keep in mind that the subnavbar title is automatically assigned, but you can overwrite it with this store, the description of the will not automatically be assigned, so the only way is through the store.
<script lang="ts">
import {
getSubNavbarStore,
type SubNavbarSettings,
} from '@tanglemedia/svelte-starter-layout';
import { onDestroy } from 'svelte';
const subNavbarStore = getSubNavbarStore();
const subNavbar: SubNavbarSettings = {
value: {
title: 'Add single item',
description: 'Page to add single item'
}
};
$: subNavbarStore.set(subNavbar);
onDestroy(() => {
subNavbarStore.clear();
});
</script>
- BreadcrumbStore: This store makes you able to manually set the value of the breadcrumb items. Keep in mind that the breadcrumb items are automatically assigned, but you can overwrite it with this store.
<script lang="ts">
import {
getBreadcrumbStore,
type BreadcrumbSettings
} from '@tanglemedia/svelte-starter-layout';
import { onDestroy } from 'svelte';
const breadcrumbStore = getBreadcrumbStore();
const breadcrumb: BreadcrumbSettings = {
value: [
{
title: 'Dashboard',
url: '/dashboard'
},
{
title: 'Add',
url: '/dashboard/add'
},
{
title: 'Item',
url: '/dashboard/add/1'
}
]
};
$: breadcrumbStore.set(breadcrumb);
onDestroy(() => {
breadcrumbStore.clear();
});
</script>
- sidebarStore: This store makes you able to manually set the value of the sidebar, to either show as cropped or not cropped. Keep in mind that the sidebar cropped or not are internal functions already, but if you want to set cropped as default, you could do it through this store.
<script lang="ts">
import {
getSidebarStore,
type SidebarSettings
} from '@tanglemedia/svelte-starter-layout';
import { onDestroy } from 'svelte';
const sidebarStore = getSidebarStore();
const sidebar: SidebarSettings = {
// open or closed
value: 'open'
};
sidebarStore.set(sidebar);
</script>
Migrating from 1.0.0 to 2.0.0
On this new major version of the library, the library went through a HUGE redesign, and with that, NEW & EXCITING features were added 🤟, here is a list of all new features:
- Slot Forwarding & Slot Overwrites
- New Sidebars & SubItems
- New SubHeaders
- New Footers
- New Headers
With all of these new features, the library increased A LOT on the YML CONFIG side as well, here are a list of all new yml files:
- footer.yml
- hamburger.yml
- header.yml
- sidebar.yml
These were the new yml files added to this version of the library, BUT there were MAJOR changes on other yml files as well, (layout.yml), with lots of more fields added to it. Here is an example of the new layout.yml file:
New Component & Features
Slot Forwarding & Slot Overwrites
We made sure you could overwrite lots of components by just passing the slot directly to the component.
We have about 34 slots + main slot (content) you can pass to the component to overwrite some components completely.
16 of these slots are just for the Header part of you component, and the slots are:
hamburger-icon
- This slot is responsible for overwriting the hamburger default icon
hamburger-drawer
- This slot is responsible for overwriting the Default drawer component that gets rendered when the hamburger button is clicked.
hamburger
- This slot is responsible for overwriting completely the default hamburger menu button and it's functionality.
before-logo
- This slot is responsible for overwriting the left side of the logo, by default this is empty
logo
- This slot is responsible for displaying the logo and the hamburger menu
- If have hamburger display as true, then on you hamburger hide value it will display the logo or display the hamburger menu
- If you have hamburger display as false, it will always just display the logo
after-logo
- This slot is responsible for overwriting the right side of the logo, by default this displays the page title / location
center
- This slot is responsible for overwriting the center of the header component, by default is empty
right
- This slot is responsible for overwriting the right side of the header component, by default this displays the ProfileButton component
sub-header
- This slot is responsible for overwriting the entire subHeader component and its functionality.
subheader-left-side
- This slot is responsible for overwriting the left side of the subHeader component, by default is empty or could display the component passed to the subHeaderStore.
subheader-title
- This slot is responsible for overwriting the title of the subHeader component, by default this slot has a few functionalities to display the title.
- The title could be set by passing directly to the component, by passing to the layout.yml (layout.header.subHeader.defaultTitle), by passing it to the subHeaderStore, or by default it will display the location title, i.e. if the pathname is '/dashboard/person/add' it would display 'Add'.
subheader-description
- This slot is responsible for overwriting the description of the subHeader component, by default this slot is empty.
- The description could be set by passing directly to the component, by passing to the layout.yml (layout.header.subHeader.defaultDescription), by passing it to the subHeaderStore.
subheader-right-side
- This slot is responsible for overwriting the right side of the subHeader component, by default is empty or could display the component passed to the subHeaderStore, and position is right.
header-navigation
- This slot is responsible for overwriting the entire HeaderNavigation component and its functionality.
header-navigation-list
- This slot is responsible for overwriting the entire list of navigation items of the HeaderNavigation component, by default this displays the navigation items of the NavigationHeader component.
header-navigation-extra-info
- This slot is responsible for adding extra information on the right side of the navigation header menu. By default this slot is empty.
18 of these slots are just for the Sidebar part of your component, but because we have 3 different sidebars and 2 different sides, the total slots are 18, but it is actually just 3 functionalities and their variations for side and sidebar type. The slots are:
side: left or right type: minimal, default, detailed
- app-sidebar-{side}-{type}-top
- This slot is responsible for adding extra information at the top of the sidebar. By default this slot is empty.
- app-sidebar-{side}-{type}-bottom
- This slot is responsible for overwriting the list of sidebar items displayed on the sidebar by default.
- app-sidebar-{side}-{type}-center
- This slot is responsible for adding extra information at the bottom of the sidebar. By default this slot is empty.
New Sidebars & SubItems
On this new update, we redesigned the sidebars and created three different styles of sidebar as well as being able to pass them to either the left side or the right side.
You have access to all the sidebar components:
- AppSidebar
- AppSidebarMinimal
- AppSidebarDefault
They all have their different style, here is a short summary: The Minimal is a very simple sidebar, Default is similar to the minimal but a little bigger and displays the titles, and the Detailed one displays the icon and title on a vertical style.
But you should be able to call them by just using the yml files. By setting the sidebar list and enabled value on layout.yml:
sidebar:
# LIST: list of sidebar components you want to display, you can pass whatever name you want to this list
list: ['main']
# ENABLED: make sure this is TRUE if you want to display the sidebar components
enabled: true
And the sidebar.yml file:
components:
## MAKE SURE THE KEY NAME OF YOUR COMPONENTS FIELD IS THE SAME AS THE ONES IN THE LIST
main:
# STYLE: defines the style of the sidebar
style: 'default' #default, minimal, detailed
# POSITION: defines the side where the sidebar is displayed, i.e. left or right
position: 'left'
# OPTIONAL
containerClass: 'bg-white'
# OPTIONAL
listClass: ''
# OPTIONAL
activeBgClass: ''
# OPTIONAL
activeTextClass: ''
# OPTIONAL
activeIconClass: ''
# OPTIONAL
bgClass: ''
# OPTIONAL
textClass: ''
# OPTIONAL
iconClass: ''
# OPTIONAL
floatingBtnClass: ''
# OPTIONAL
floatingBtnIcon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'md'
# OPTIONAL
subSidebarClass: ''
items:
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Dashboard
href: /dashboard
# OPTIONAL
items:
- title: Dashboard 7
href: /dashboard/7
items:
- title: Dashboard 10
href: /dashboard/10
- title: Dashboard 8
href: /dashboard/8
- title: Dashboard 9
href: /dashboard/9
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Profile
href: /profile
New SubHeaders
On this new update, we redesigned the SubHeader component, earlier known as SubNavbarComponent.
On the new component you are able to choose if you want to display this component only on for mobile screens or display it all the time.
You are also able to overwrite what gets displayed on it by the SubHeaderStore, and even pass components to either left or right side of it.
You have acces to all the sub header components:
- AppSubHeader
- AppSubHeaderItem But you should be able to call them by just using the layout.yml file. By setting the enabled or mobile field to true:
subHeader:
## ENABLED: Display component for all screens
enabled: false
## MOBILE: Display component for MOBILE screens
mobile: true
# OPTIONAL
defaultTitle: ''
# OPTIONAL
defaultDescription: 'Welcome to Tangle Media'
# OPTIONAL
bgImage: 'src/lib/assets/background.png'
# OPTIONAL
opacity: 50
# OPTIONAL
class: 'text-white'
# OPTIONAL
filterClass: 'bg-primary'
# OPTIONAL
leftSideClass: ''
# OPTIONAL
centerSideClass: 'lg:ml-24'
# OPTIONAL
rightSideClass: ''
# OPTIONAL
titleClass: ''
# OPTIONAL
descriptionClass: ''
New Footers
The Footer component got a few new features and configuration on this new version.
You have access to all the Footer components:
- AppFooterDefault
- AppFooterPill
- AppFooterItem
But you should be able to call them by just using the layout.yml file. by the footer list and enabled or mobile value to true.
footer:
list: ['main']
enabled: false
mobile: true
showTitle: true
And on the footer.yml file:
components:
## MAKE SURE THE KEY NAME OF YOUR COMPONENTS FIELD IS THE SAME AS THE ONES IN THE LIST
main:
# STYLE: defines the style of the footer
style: 'pill' # default or pill
# POSITION: defines the footer side, experimental, 'bottom' the only working as for rn
position: 'bottom'
# OPTIONAL
activeBgClass: ''
# OPTIONAL
activeTextClass: 'text-secondary'
# OPTIONAL
activeIconClass: ''
# OPTIONAL
listClass: ''
# OPTIONAL
baseClass: 'py-1 variant-filled-primary'
# OPTIONAL
textClass: 'text-slate-100'
# OPTIONAL
iconClass: 'text-slate-100'
items:
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Dashboard
href: /dashboard
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Profile
href: /profile
New Headers
On this new update, we slightly redesigned the AppHeader component, not as much as any of the other components, but still some new features were added to it.
As were mentioned above, we have now a SubHeader component. Bu we also have a HeaderNavigation component as well that is displayed on the AppHeader component.
Besides that, the Header component still displays the logo, hamburger, breadcrumbs, and the ProfileButton. ALthough now all of that is possible to be overwritten by passing the slots values.
You have access to all the Header Navigation components:
- AppHeaderNavigation
- AppHeaderNavigationItem
But you should be able to call them by just using the layout.yml file and the new header.yml file. on the layout.yml file if you want the Header Navigation to be parlt of you navigation system, you have to add 'header' to the navigation field on the layout.yml:
display:
mode: desktop
navigation: ['header', 'sidebar']
#......
After that, o the header.yml you should setup how you want the Header Navigation to be displayed:
navigation:
mobile:
hamburger:
icon: 'hamburger'
hide: 'lg'
display: true
truncate:
text: '...'
hide: 'lg'
display: true
hide: 'md' #xs, sm, md, lg, xl, 2xl, none
# OPTIONAL
containerClass: ''
# OPTIONAL
listClass: 'lg:pl-20'
# OPTIONAL
listItemClass: ''
# OPTIONAL
activeBgClass: ''
# OPTIONAL
activeTextClass: ''
# OPTIONAL
bgClass: ''
# OPTIONAL
textClass: ''
# OPTIONAL
iconClass: ''
# OPTIONAL
underlineClass: ''
items:
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'lg'
title: Dashboard
href: /dashboard
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'lg'
title: Profile
href: /profile
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'lg'
title: Dashboard 1
href: /dashboard/1
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'lg'
title: Dashboard 2
href: /dashboard/2
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'lg'
title: Dashboard 3
href: /dashboard/3
New YML Files & Fields examples:
New layout.yml
display:
mode: desktop #desktop #mobile
navigation: ['header', 'sidebar'] #header #sidebar
# Global settings
header:
enabled: true
logo: 'src/lib/assets/small_logo_white.png'
logoHref: '/dashboard'
logoClass: 'w-10 mr-10 ml-3'
defaultTitle: ''
containerClass: ''
class: ''
leftSideClass: ''
centerSideClass: ''
rightSideClass: ''
profileButton:
enabled: true
defaultLink: '/profile'
iconHexColor: '#fff'
links:
- name: Profile
href: /profile
- name: Change Password
href: /profile?tab=change_password
subHeader:
enabled: false
mobile: true
defaultTitle: ''
defaultDescription: 'Welcome to Tangle Media'
bgImage: 'src/lib/assets/background.png'
opacity: 50
class: 'text-white'
filterClass: 'bg-primary'
leftSideClass: ''
centerSideClass: 'lg:ml-24'
rightSideClass: ''
titleClass: ''
descriptionClass: ''
sidebar:
list: ['main', 'right']
enabled: true
footer:
list: ['main']
enabled: false
mobile: true
showTitle: true
New footer.yml
components:
main:
style: 'pill' # default or pill
position: 'bottom'
activeBgClass: ''
activeTextClass: 'text-secondary'
activeIconClass: ''
listClass: ''
baseClass: 'py-1 variant-filled-primary'
textClass: 'text-slate-100'
iconClass: 'text-slate-100'
items:
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Dashboard
href: /dashboard
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Profile
href: /profile
New hamburger.yml
logo: 'src/lib/assets/full_logo.png'
logoHref: '/dashboard'
logoClass: 'h-12 w-auto'
containerClass: ''
listClass: ''
activeBgClass: ''
activeTextClass: ''
activeIconClass: ''
bgClass: ''
textClass: ''
iconClass: ''
items:
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Dashboard
href: /dashboard
items:
- title: Dashboard 2
href: /dashboard/2
items:
- title: Dashboard 3
href: /dashboard/3
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Dashboard 4
href: /dashboard/4
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Dashboard 5
href: /dashboard/5
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Profile
href: /profile
New header.yml
navigation:
mobile:
hamburger:
icon: 'hamburger'
hide: 'lg'
display: true
truncate:
text: '...'
hide: 'lg'
display: true
hide: 'md' #xs, sm, md, lg, xl, 2xl, none
containerClass: ''
listClass: 'lg:pl-20'
listItemClass: ''
activeBgClass: ''
activeTextClass: ''
bgClass: ''
textClass: ''
iconClass: ''
underlineClass: ''
items:
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'lg'
title: Dashboard
href: /dashboard
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'lg'
title: Profile
href: /profile
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'lg'
title: Dashboard 1
href: /dashboard/1
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'lg'
title: Dashboard 2
href: /dashboard/2
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'lg'
title: Dashboard 3
href: /dashboard/3
New sidebar.yml
components:
main:
style: 'default' #default, minimal, detailed
position: 'left'
containerClass: 'bg-white'
listClass: ''
activeBgClass: ''
activeTextClass: ''
activeIconClass: ''
bgClass: ''
textClass: ''
iconClass: ''
floatingBtnClass: ''
floatingBtnIcon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'md'
subSidebarClass: ''
items:
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Dashboard
href: /dashboard
items:
- title: Dashboard 7
href: /dashboard/7
items:
- title: Dashboard 10
href: /dashboard/10
- title: Dashboard 8
href: /dashboard/8
- title: Dashboard 9
href: /dashboard/9
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Profile
href: /profile
right:
style: 'detailed' #default, minimal, detailed
position: 'right'
containerClass: 'bg-white'
listClass: ''
activeBgClass: 'variant-filled-primary'
activeTextClass: ''
activeIconClass: ''
bgClass: ''
textClass: ''
iconClass: ''
items:
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Dashboard
href: /dashboard
items:
- title: Dashboard 4
href: /dashboard/4
items:
- title: Dashboard 11
href: /dashboard/11
- title: Dashboard 5
href: /dashboard/5
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Dashboard 2
href: /dashboard/1
items:
- title: Dashboard 6
href: /dashboard/6
- icon:
active: ['fas', 'cube']
base: ['fal', 'cube']
size: 'xl'
title: Dashboard 3
href: /dashboard/2