@lsw-abpvue/theme-basic
| Install | |
|---|---|
npm install @lsw-abpvue/theme-basic |
|
| Latest Version: | 0.1.0 |
| Vue: | 3 |
| License: | MIT |
| Last Updated: | Oct 22, 2026 |
| Links: | GitHub · npm |
@lsw-abpvue/theme-basic
The default theme of Lsw.Abp.VueUI, an
unofficial Vue UI for the ABP Framework. The twelve contracts of
@lsw-abpvue/theme-shared implemented with reka-ui for behaviour
and Bootstrap 5 for looks, plus the three layouts an ABP application is rendered in.
pnpm add @lsw-abpvue/theme-basic bootstrap bootstrap-icons
reka-ui brings vue-demi with it (through @floating-ui/vue), and vue-demi writes its
Vue 2 / Vue 3 shim in a postinstall script. pnpm asks before running one, so allow it:
# pnpm-workspace.yaml
allowBuilds:
vue-demi: true
Setup
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap-icons/font/bootstrap-icons.css';
import '@lsw-abpvue/theme-basic/style.css';
import { createAbpApp, provideAbpCore, withOptions } from '@lsw-abpvue/core';
import { provideAbpRouter } from '@lsw-abpvue/core/router';
import { provideAbpThemeBasic } from '@lsw-abpvue/theme-basic';
const { mount } = await createAbpApp(App, {
providers: [
provideAbpCore(withOptions({ environment })),
provideAbpRouter(routes),
provideAbpThemeBasic(),
],
});
The application component is the layout switch and nothing else:
<template>
<AbpDynamicLayout :default-layout="LayoutType.application">
<RouterView />
</AbpDynamicLayout>
</template>
Bootstrap's CSS only. Its JavaScript is never loaded — dialogs, dropdowns, selects and pagination are reka-ui, which brings the focus management, the ARIA and the keyboard handling with it.
Date and date-time fields use reka-ui's calendar and keyboard-editable segments; time fields use its time field. ABP's culture patterns control order, separators and widths. An untouched ISO value retains its original precision and offset. Editing emits a local ISO date or time without applying a browser time-zone conversion.
Keep the stylesheet imports before the theme's JavaScript import. This also preserves the cascade when consuming the theme directly from source during development.
The three layouts
Theme.ApplicationLayoutComponent |
sidebar, navbar, breadcrumb, the page |
Theme.AccountLayoutComponent |
a centred card, for login and register |
Theme.EmptyLayoutComponent |
the page, and the toast and dialog hosts |
The menu is RoutesService.groupedVisible rendered directly: already filtered by policy,
sorted and grouped, so a route whose permission was just granted appears on its own.
Collapsed state is remembered; under 992px the sidebar becomes a drawer.
Every piece is registered through ReplaceableComponentsService, so a host replaces one
without forking the theme:
replaceable.add({ key: ThemeBasicComponents.Logo, component: MyLogo });
The account shell
The account layout wraps every page it shows in Account.AuthWrapperComponent: the card,
the tenant box above it, and the notice that goes up in place of the form when the client
has no login scheme of its own. Both it and Account.TenantBoxComponent are replaceable
under the keys the Angular UI uses.
Switching tenant is @lsw-abpvue/account-core's TenantBoxService, which answers whether
the name was found; the toast that says it was not is the theme's. A route can set
meta.tenantBoxVisible: false to leave the box out, which is what the reset password page
does.
Dark mode and right to left
Dark mode is Bootstrap's own data-bs-theme, set by ThemeModeService, which follows
the operating system until someone chooses and then remembers the choice. The navbar
carries a toggle for it.
Right to left follows the language: ABP says which cultures read that way, and
DirectionService puts dir on the document when one is chosen. The theme's own styles
use logical properties throughout, so nothing else has to know.
Theming
Everything themable is a custom property, and no component style names a colour:
:root {
--abp-accent: #5145cd;
--abp-accent-rgb: 81, 69, 205;
--abp-sidebar-width: 18rem;
--abp-sidebar-bg: var(--bs-body-bg);
--abp-loader-bar-color: rebeccapurple;
}
The Bootstrap controls and semantic table classes share --abp-surface,
--abp-canvas, --abp-border, --abp-text and --abp-muted. Override these variables
for each data-bs-theme when customizing both modes.
Contract tests
The theme runs the suite theme-shared exports, which is the definition of done for any
theme:
import { runThemeContractTests } from '@lsw-abpvue/theme-shared/testing';
import { provideAbpThemeBasic } from '@lsw-abpvue/theme-basic';
runThemeContractTests({ name: 'basic', providers: [provideAbpThemeBasic()] });
Compared with the Angular UI
@abp/ng.theme.basic is the same three layouts against the same component keys, so a
host that replaces Theme.ApplicationLayoutComponent there replaces it here. What is
different: dark mode exists (in the Angular UI it is what LeptonX is for), the icons are
Bootstrap Icons rather than Font Awesome, and none of Bootstrap's JavaScript is shipped.
Licence
MIT. Bootstrap and Bootstrap Icons are MIT; reka-ui is MIT. Its date companion,
@internationalized/date, is Apache-2.0 and supplies calendar value parsing.
Related Packages
The theme contract of the ABP Vue UI: twelve component interfaces, the state ser...
Official Bootstrap 5 starter theme for Freeform (React & Vue)
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.1.0 | ^3.5.0 | MIT |
Pre-releases (6)
| Version | Released | Vue | License |
|---|---|---|---|
| 0.0.1-alpha.5 | ^3.5.0 | MIT | |
| 0.0.1-alpha.4 | ^3.5.0 | MIT | |
| 0.0.1-alpha.3 | ^3.5.0 | MIT | |
| 0.0.1-alpha.2 | ^3.5.0 | MIT | |
| 0.0.1-alpha.1 | ^3.5.0 | MIT | |
| 0.0.1-alpha.0 | ^3.5.0 | MIT |