@lsw-abpvue/theme-basic

The default theme of the ABP Vue UI: the twelve contracts on reka-ui, the three layouts, and Bootstrap 5 for looks.
1,044 3
Install
npm install @lsw-abpvue/theme-basic
Latest Version:0.1.0
Vue:3
License:MIT
Last Updated:Oct 22, 2026
Links: GitHub  ·  npm
Maintainer: shiweiliang

@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

@lsw-abpvue/theme-shared

The theme contract of the ABP Vue UI: twelve component interfaces, the state ser...

1,289 3
@solspace/freeform-theme-bootstrap

Official Bootstrap 5 starter theme for Freeform (React & Vue)

1,051
vue-multiselect-bootstrap-theme

Bootstrap 3/4/5 themes for vue-multiselect

8,906 6
tailwindcss-themeable

multiple themes support for tailwindcss, with Dracula built-in

7,097 59
vueboot

A collection of Vuejs components that wrap Bootstrap components

4,245

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