diff --git a/docs/en/Themes/LeptonXLite/Angular.md b/docs/en/Themes/LeptonXLite/Angular.md
index 4079281f99..950cd20c8b 100644
--- a/docs/en/Themes/LeptonXLite/Angular.md
+++ b/docs/en/Themes/LeptonXLite/Angular.md
@@ -1,7 +1,8 @@
# LeptonX Lite Angular UI
+
LeptonX Lite has implementation for the ABP Framework Angular Client. It's a simplified variation of the [LeptonX Theme](https://x.leptontheme.com/).
-> If you are looking for a professional, enterprise ready theme, you can check the [LeptonX Theme](https://x.leptontheme.com/), which is a part of [ABP Commercial](https://commercial.abp.io/).
+> If you are looking for a professional, enterprise ready theme, you can check the [LeptonX Theme](https://x.leptontheme.com/), which is a part of [ABP Commercial](https://commercial.abp.io/).
> See the [Theming document](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Theming) to learn about themes.
@@ -11,28 +12,27 @@ This theme is **already installed** when you create a new solution using the sta
To add `LeptonX-lite` into your project,
-* Install `@abp/ng.theme.lepton-x`
+- Install `@abp/ng.theme.lepton-x`
`yarn add @abp/ng.theme.lepton-x@preview`
-* Install `bootstrap-icons`
+- Install `bootstrap-icons`
`yarn add bootstrap-icons`
+- Then, we need to edit the styles array in `angular.json` to replace the existing style with the new one.
-* Then, we need to edit the styles array in `angular.json` to replace the existing style with the new one.
-
-Add the following style
+Add the following style
```json
"node_modules/bootstrap-icons/font/bootstrap-icons.css",
```
-* Finally, remove `ThemeBasicModule` from `app.module.ts`, and import the related modules in `app.module.ts`
+- Finally, remove `ThemeBasicModule` from `app.module.ts`, and import the related modules in `app.module.ts`
```js
-import { ThemeLeptonXModule } from '@abp/ng.theme.lepton-x';
-import { SideMenuLayoutModule } from '@abp/ng.theme.lepton-x/layouts';
+import { ThemeLeptonXModule } from "@abp/ng.theme.lepton-x";
+import { SideMenuLayoutModule } from "@abp/ng.theme.lepton-x/layouts";
@NgModule({
imports: [
@@ -51,7 +51,7 @@ export class AppModule {}
Note: If you employ [Resource Owner Password Flow](https://docs.abp.io/en/abp/latest/UI/Angular/Authorization#resource-owner-password-flow) for authorization, you should import the following module as well:
```js
-import { AccountLayoutModule } from '@abp/ng.theme.lepton-x/account';
+import { AccountLayoutModule } from "@abp/ng.theme.lepton-x/account";
@NgModule({
// ...
@@ -69,15 +69,15 @@ To change the logos and brand color of `LeptonX`, simply add the following CSS t
```css
:root {
- --lpx-logo: url('/assets/images/logo.png');
- --lpx-logo-icon: url('/assets/images/logo-icon.png');
+ --lpx-logo: url("/assets/images/logo.png");
+ --lpx-logo-icon: url("/assets/images/logo-icon.png");
--lpx-brand: #edae53;
}
```
- `--lpx-logo` is used to place the logo in the menu.
-- `--lpx-logo-icon` is a square icon used when the menu is collapsed.
-- `--lpx-brand` is a color used throughout the application, especially on active elements.
+- `--lpx-logo-icon` is a square icon used when the menu is collapsed.
+- `--lpx-brand` is a color used throughout the application, especially on active elements.
### Server Side
@@ -85,22 +85,18 @@ In order to migrate to LeptonX on your server side projects (Host and/or AuthSer
## Customization
-
### Layouts
-The Angular version of LeptonX Lite provides **layout components** for your **user interface** on [ABP Framework Theming](https://docs.abp.io/en/abp/latest/UI/Angular/Theming). You can use layouts to **organize your user interface**. You can replace the **layout components** and some parts of the **layout components** with the [ABP replaceable component system](https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement).
-
+The Angular version of LeptonX Lite provides **layout components** for your **user interface** on [ABP Framework Theming](https://docs.abp.io/en/abp/latest/UI/Angular/Theming). You can use the layouts to **organize your user interface**. You can replace the **layout components** and some parts of the **layout components** with the [ABP replaceable component system](https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement).
The main responsibility of a theme is to **provide** the layouts. There are **three pre-defined layouts that must be implemented by all the themes:**
-* **ApplicationLayoutComponent:** The **default** layout which is used by the **main** application pages.
-
-* **AccountLayoutComponent:** Mostly used by the **account module** for **login**, **register**, **forgot password**... pages.
-
-* **EmptyLayoutComponent:** The **Minimal** layout that **has no layout components** at all.
+- **ApplicationLayoutComponent:** The **default** layout which is used by the **main** application pages.
+- **AccountLayoutComponent:** Mostly used by the **account module** for **login**, **register**, **forgot password**... pages.
+- **EmptyLayoutComponent:** The **Minimal** layout that **has no layout components** at all.
+
+The **Layout components** and all the replacable components are predefined in `eThemeLeptonXComponents` as enum.
- The **Layout components** and all the replacable components are predefined in `eThemeLeptonXComponents` as enum.
-
### How to replace a component
```js
@@ -122,8 +118,8 @@ export class AppComponent {
}
}
```
-See the [Component Replacement](https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement) documentation for more information on how to replace components.
+See the [Component Replacement](https://docs.abp.io/en/abp/latest/UI/Angular/Component-Replacement) documentation for more information on how to replace components.
### Brand Component
@@ -131,16 +127,14 @@ The **brand component** is a simple component that can be used to display your b
```js
///...
- this.replaceableComponents.add({
- component: YourNewLogoComponent,
- key: eThemeLeptonXComponents.Logo,
- });
+this.replaceableComponents.add({
+ component: YourNewLogoComponent,
+ key: eThemeLeptonXComponents.Logo,
+});
///...
```
-
-
-
+
## Breadcrumb Component
@@ -148,14 +142,14 @@ On websites that have a lot of pages, **breadcrumb navigation** can greatly **en
```js
///...
- this.replaceableComponents.add({
- component: YourNewSidebarComponent,
- key: eThemeLeptonXComponents.Breadcrumb,
- });
+this.replaceableComponents.add({
+ component: YourNewSidebarComponent,
+ key: eThemeLeptonXComponents.Breadcrumb,
+});
///...
```
-
+
## Sidebar Menu Component
@@ -163,54 +157,61 @@ Sidebar menus have been used as a **directory for Related Pages** to a **Service
```js
///...
- this.replaceableComponents.add({
- component: YourNewSidebarComponent,
- key: eThemeLeptonXComponents.Sidebar,
- });
+this.replaceableComponents.add({
+ component: YourNewSidebarComponent,
+ key: eThemeLeptonXComponents.Sidebar,
+});
///...
```
-
+
+
## Page Alerts Component
Provides contextual **feedback messages** for typical user actions with a handful of **available** and **flexible** **alert messages**. Alerts are available for any length of text, as well as an **optional dismiss button**.
-
+
+
```js
///...
- this.replaceableComponents.add({
- component: YourNewPageAlertContainerComponent,
- key: eThemeLeptonXComponents.PageAlertContainer,
- });
+this.replaceableComponents.add({
+ component: YourNewPageAlertContainerComponent,
+ key: eThemeLeptonXComponents.PageAlertContainer,
+});
///...
```
+
## Toolbar Component
+

Toolbar items are used to add **extra functionality to the toolbar**. The toolbar is a **horizontal bar** that **contains** a group of **toolbar items**.
+
```js
///...
- this.replaceableComponents.add({
- component: YourNewNavItemsComponent,
- key: eThemeLeptonXComponents.NavItems,
- });
+this.replaceableComponents.add({
+ component: YourNewNavItemsComponent,
+ key: eThemeLeptonXComponents.NavItems,
+});
///...
```
## Toolbar Items
+
There are two parts to the toolbar. The first is Language-Switch. The second is the User-Profile element. You can swap out each of these parts individually.
## Language Switch Component
-Think about a **multi-lingual** website and the first thing that could **hit your mind** is **the language switch component**. A **navigation bar** is a **great place** to **embed a language switch**. By embedding the language switch in the navigation bar of your website, you would **make it simpler** for users to **find it** and **easily** switch the **language** **without trying to locate it across the website.**
+Think about a **multi-lingual** website and the first thing that could **hit your mind** is **the language switch component**. A **navigation bar** is a **great place** to **embed a language switch**. By embedding the language switch in the navigation bar of your website, you would **make it simpler** for users to **find it** and **easily** switch the **language** **without trying to locate it across the website.**
+
+
-
```js
///...
- this.replaceableComponents.add({
- component: YourNewLanguagesComponent,
- key: eThemeLeptonXComponents.Languages,
- });
+this.replaceableComponents.add({
+ component: YourNewLanguagesComponent,
+ key: eThemeLeptonXComponents.Languages,
+});
///...
```
@@ -219,33 +220,84 @@ Think about a **multi-lingual** website and the first thing that could **hit you
The **User Menu** is the **menu** that **drops down** when you **click your name** or **profile picture** in the **upper right corner** of your page (**in the toolbar**). It drops down options such as **Settings**, **Logout**, etc.

+
```js
///...
- this.replaceableComponents.add({
- component: YourNewCurrentUserComponent,
- key: eThemeLeptonXComponents.CurrentUser,
- });
+this.replaceableComponents.add({
+ component: YourNewCurrentUserComponent,
+ key: eThemeLeptonXComponents.CurrentUser,
+});
///...
```
+
Note: The language selection component in the Volo app is not replaceable. It is part of the settings menu.
## Mobile Navbar Component
+
The **mobile navbar component** is used to display the **navbar menu on mobile devices**. The mobile navbar component is a **dropdown menu** that contains language selection and user menu.
-
+
+
```js
///...
- this.replaceableComponents.add({
- component: YourNewMobileNavbarComponent,
- key: eThemeLeptonXComponents.MobileNavbar,
- });
+this.replaceableComponents.add({
+ component: YourNewMobileNavbarComponent,
+ key: eThemeLeptonXComponents.MobileNavbar,
+});
///...
```
+
## Mobile Navbar Items.
-There are two parts of the mobile navbar. The mobile navbar has Language-Switch and User-Profile. You can swap out each of these parts individually.
+
+There are two parts of the mobile navbar. The mobile navbar has Language-Switch and User-Profile. You can swap out each of these parts individually.
The Mobile language-Selection component key is `eThemeLeptonXComponents.MobileLanguageSelection`.
The Mobile User-Profile component key is `eThemeLeptonXComponents.MobileUserProfile`.
+## Footer Component
+
+
+
+The Footer is the section of content at the very bottom of the site. This section of the content can be modified.
+Inject **FooterLinksService** and use the **setFooterInfo** method of **FooterLinksService**
+to assign path or link and description.
+**descUrl** and **footerLinks** are nullable. Constant **footerLinks** are on the right side of footer.
+
+
+```js
+///...
+
+const footerLinks = [
+ {
+ link: "/components/bootstrap/badge",
+ text: "Manage Your Profile",
+ },
+ {
+ link: "/components/bootstrap/border",
+ text: "My Security Logs",
+ },
+];
+
+const footerInfo: FooterNav = {
+ desc: "Home",
+ descUrl: "/components/home",
+ footerLinks: footerLinks,
+};
+
+this.footerLinksService.setFooterInfo(footerInfo);
+
+///...
+```
+If you want to change the footer component, the key is `eThemeLeptonXComponents.Footer`
+
+```js
+///...
+this.replaceableComponents.add({
+ component: YourNewFooterComponent,
+ key: eThemeLeptonXComponents.Footer,
+});
+///...
+```
+
diff --git a/docs/en/images/angular-footer.png b/docs/en/images/angular-footer.png
new file mode 100644
index 0000000000..16be8194ab
Binary files /dev/null and b/docs/en/images/angular-footer.png differ
diff --git a/npm/ng-packs/packages/schematics/src/collection.json b/npm/ng-packs/packages/schematics/src/collection.json
index 8441a786b0..16f148d78a 100644
--- a/npm/ng-packs/packages/schematics/src/collection.json
+++ b/npm/ng-packs/packages/schematics/src/collection.json
@@ -29,6 +29,12 @@
"description": "ABP Create Library Schematics",
"factory": "./commands/create-lib",
"schema": "./commands/create-lib/schema.json"
+ },
+ "change-theme": {
+ "description": "ABP Change Styles of Theme Schematics",
+ "factory": "./commands/change-theme",
+ "schema": "./commands/change-theme/schema.json"
+
}
}
}
diff --git a/npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts b/npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts
new file mode 100644
index 0000000000..22f32be353
--- /dev/null
+++ b/npm/ng-packs/packages/schematics/src/commands/change-theme/index.ts
@@ -0,0 +1,85 @@
+import { Rule, SchematicContext, SchematicsException, Tree } from '@angular-devkit/schematics';
+import { isLibrary, updateWorkspace, WorkspaceDefinition } from '../../utils';
+import { allStyles, styleMap } from './style-map';
+import { ProjectDefinition } from '@angular-devkit/core/src/workspace';
+import { JsonArray, JsonValue } from '@angular-devkit/core';
+import { ChangeThemeOptions } from './model';
+import { ThemeOptionsEnum } from './theme-options.enum';
+
+export default function (_options: ChangeThemeOptions): Rule {
+ return async (_: Tree, __: SchematicContext) => {
+ const targetThemeName = _options.name;
+ const selectedProject = _options.targetProject;
+ if (!targetThemeName) {
+ throw new SchematicsException('The theme name does not selected');
+ }
+
+ return updateWorkspace(storedWorkspace => {
+ updateProjectStyle(selectedProject, storedWorkspace, targetThemeName);
+ });
+ };
+}
+
+function updateProjectStyle(
+ projectName: string,
+ workspace: WorkspaceDefinition,
+ targetThemeName: ThemeOptionsEnum,
+) {
+ const project = workspace.projects.get(projectName);
+
+ if (!project) {
+ throw new SchematicsException('The target project does not selected');
+ }
+
+ const isProjectLibrary = isLibrary(project);
+ if (isProjectLibrary) {
+ throw new SchematicsException('The library project does not supported');
+ }
+
+ const targetOption = getProjectTargetOptions(project, 'build');
+ const styles = targetOption.styles as (string | { input: string })[];
+
+ const sanitizedStyles = removeThemeBasedStyles(styles);
+
+ const newStyles = styleMap.get(targetThemeName);
+ if (!newStyles) {
+ throw new SchematicsException('The theme does not found');
+ }
+ targetOption.styles = [...newStyles, ...sanitizedStyles] as JsonArray;
+}
+
+export function getProjectTargetOptions(
+ project: ProjectDefinition,
+ buildTarget: string,
+): Record {
+ const options = project.targets?.get(buildTarget)?.options;
+
+ if (!options) {
+ throw new SchematicsException(
+ `Cannot determine project target configuration for: ${buildTarget}.`,
+ );
+ }
+
+ return options;
+}
+
+export function removeThemeBasedStyles(styles: (string | object)[]) {
+ return styles.filter(s => !allStyles.some(x => styleCompareFn(s, x)));
+}
+
+export const styleCompareFn = (item1: string | object, item2: string | object) => {
+ const type1 = typeof item1;
+ const type2 = typeof item1;
+
+ if (type1 !== type2) {
+ return false;
+ }
+
+ if (type1 === 'string') {
+ return item1 === item2;
+ }
+ const o1 = item1 as { bundleName?: string };
+ const o2 = item2 as { bundleName?: string };
+
+ return o1.bundleName && o2.bundleName && o1.bundleName == o2.bundleName;
+};
diff --git a/npm/ng-packs/packages/schematics/src/commands/change-theme/model.ts b/npm/ng-packs/packages/schematics/src/commands/change-theme/model.ts
new file mode 100644
index 0000000000..ca553c50c7
--- /dev/null
+++ b/npm/ng-packs/packages/schematics/src/commands/change-theme/model.ts
@@ -0,0 +1,6 @@
+import { ThemeOptionsEnum } from './theme-options.enum';
+
+export type ChangeThemeOptions = {
+ name: ThemeOptionsEnum;
+ targetProject: string;
+};
diff --git a/npm/ng-packs/packages/schematics/src/commands/change-theme/schema.json b/npm/ng-packs/packages/schematics/src/commands/change-theme/schema.json
new file mode 100644
index 0000000000..6eb6bc71a5
--- /dev/null
+++ b/npm/ng-packs/packages/schematics/src/commands/change-theme/schema.json
@@ -0,0 +1,37 @@
+{
+ "$schema": "http://json-schema.org/schema",
+ "$id": "SchematicsABPThemeChanger",
+ "title": "ABP Theme Style Generator API Schema",
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "The name of theme will change.",
+ "type": "number",
+ "$default": {
+ "$source": "argv",
+ "index": 0
+ },
+ "enum": [1, 2, 3, 4],
+ "x-prompt": {
+ "message": "Which theme would you like to use?",
+ "type": "list",
+ "items": [
+ { "value": 1, "label": "Basic" },
+ { "value": 2, "label": "Lepton" },
+ { "value": 3, "label": "LeptonXLite" },
+ { "value": 4, "label": "LeptonX" }
+ ]
+ }
+ },
+ "targetProject": {
+ "description": "The name of the project will change the style.The project type must be 'application'",
+ "type": "string",
+ "x-prompt": "Please enter the project name",
+ "$default": {
+ "$source": "argv",
+ "index": 1
+ }
+ }
+ },
+ "required": ["name"]
+}
diff --git a/npm/ng-packs/packages/schematics/src/commands/change-theme/style-map.ts b/npm/ng-packs/packages/schematics/src/commands/change-theme/style-map.ts
new file mode 100644
index 0000000000..aa5f17b21a
--- /dev/null
+++ b/npm/ng-packs/packages/schematics/src/commands/change-theme/style-map.ts
@@ -0,0 +1,223 @@
+import { ThemeOptionsEnum } from './theme-options.enum';
+
+export type StyleDefinition =
+ | {
+ input: string;
+ inject: boolean;
+ bundleName: string;
+ }
+ | string;
+
+export const styleMap = new Map();
+
+styleMap.set(ThemeOptionsEnum.Basic, [
+ {
+ input: 'node_modules/bootstrap/dist/css/bootstrap.rtl.min.css',
+ inject: false,
+ bundleName: 'bootstrap-rtl.min',
+ },
+ {
+ input: 'node_modules/bootstrap/dist/css/bootstrap.min.css',
+ inject: true,
+ bundleName: 'bootstrap-ltr.min',
+ },
+]);
+
+styleMap.set(ThemeOptionsEnum.Lepton, [
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton1.min.css',
+ inject: false,
+ bundleName: 'lepton1',
+ },
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton2.min.css',
+ inject: false,
+ bundleName: 'lepton2',
+ },
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton3.min.css',
+ inject: false,
+ bundleName: 'lepton3',
+ },
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton4.min.css',
+ inject: false,
+ bundleName: 'lepton4',
+ },
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton5.min.css',
+ inject: false,
+ bundleName: 'lepton5',
+ },
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton6.min.css',
+ inject: false,
+ bundleName: 'lepton6',
+ },
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton1.rtl.min.css',
+ inject: false,
+ bundleName: 'lepton1.rtl',
+ },
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton2.rtl.min.css',
+ inject: false,
+ bundleName: 'lepton2.rtl',
+ },
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton3.rtl.min.css',
+ inject: false,
+ bundleName: 'lepton3.rtl',
+ },
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton4.rtl.min.css',
+ inject: false,
+ bundleName: 'lepton4.rtl',
+ },
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton5.rtl.min.css',
+ inject: false,
+ bundleName: 'lepton5.rtl',
+ },
+ {
+ input: 'node_modules/@volo/abp.ng.theme.lepton/dist/global/styles/lepton6.rtl.min.css',
+ inject: false,
+ bundleName: 'lepton6.rtl',
+ },
+]);
+styleMap.set(ThemeOptionsEnum.LeptonX, [
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/dark.css',
+ inject: false,
+ bundleName: 'dark',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/light.css',
+ inject: false,
+ bundleName: 'light',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/dim.css',
+ inject: false,
+ bundleName: 'dim',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dim.css',
+ inject: false,
+ bundleName: 'bootstrap-dim',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dark.css',
+ inject: false,
+ bundleName: 'bootstrap-dark',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-light.css',
+ inject: false,
+ bundleName: 'bootstrap-light',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/ng-bundle.css',
+ inject: false,
+ bundleName: 'ng-bundle',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/side-menu/layout-bundle.css',
+ inject: false,
+ bundleName: 'layout-bundle',
+ },
+ {
+ input: 'node_modules/@volosoft/abp.ng.theme.lepton-x/assets/css/abp-bundle.css',
+ inject: false,
+ bundleName: 'abp-bundle',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/dark.rtl.css',
+ inject: false,
+ bundleName: 'dark.rtl',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/light.rtl.css',
+ inject: false,
+ bundleName: 'light.rtl',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/dim.rtl.css',
+ inject: false,
+ bundleName: 'dim.rtl',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dim.rtl.css',
+ inject: false,
+ bundleName: 'bootstrap-dim.rtl',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-dark.rtl.css',
+ inject: false,
+ bundleName: 'bootstrap-dark.rtl',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/bootstrap-light.rtl.css',
+ inject: false,
+ bundleName: 'bootstrap-light.rtl',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/ng-bundle.rtl.css',
+ inject: false,
+ bundleName: 'ng-bundle.rtl',
+ },
+ {
+ input: 'node_modules/@volosoft/ngx-lepton-x/assets/css/side-menu/layout-bundle.rtl.css',
+ inject: false,
+ bundleName: 'layout-bundle.rtl',
+ },
+ {
+ input: 'node_modules/@volosoft/abp.ng.theme.lepton-x/assets/css/abp-bundle.rtl.css',
+ inject: false,
+ bundleName: 'abp-bundle.rtl',
+ },
+]);
+styleMap.set(ThemeOptionsEnum.LeptonXLite, [
+ {
+ input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.css',
+ inject: false,
+ bundleName: 'bootstrap-dim',
+ },
+ {
+ input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.css',
+ inject: false,
+ bundleName: 'ng-bundle',
+ },
+ {
+ input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.css',
+ inject: false,
+ bundleName: 'layout-bundle',
+ },
+ {
+ input: 'node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.css',
+ inject: false,
+ bundleName: 'abp-bundle',
+ },
+ {
+ input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/bootstrap-dim.rtl.css',
+ inject: false,
+ bundleName: 'bootstrap-dim.rtl',
+ },
+ {
+ input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/ng-bundle.rtl.css',
+ inject: false,
+ bundleName: 'ng-bundle.rtl',
+ },
+ {
+ input: 'node_modules/@volo/ngx-lepton-x.lite/assets/css/side-menu/layout-bundle.rtl.css',
+ inject: false,
+ bundleName: 'layout-bundle.rtl',
+ },
+ {
+ input: 'node_modules/@abp/ng.theme.lepton-x/assets/css/abp-bundle.rtl.css',
+ inject: false,
+ bundleName: 'abp-bundle.rtl',
+ },
+]);
+// the code written by Github co-pilot. thank go-pilot. You are the best sidekick.
+export const allStyles = Array.from(styleMap.values()).reduce((acc, val) => [...acc, ...val], []);
diff --git a/npm/ng-packs/packages/schematics/src/commands/change-theme/theme-options.enum.ts b/npm/ng-packs/packages/schematics/src/commands/change-theme/theme-options.enum.ts
new file mode 100644
index 0000000000..6e2f863674
--- /dev/null
+++ b/npm/ng-packs/packages/schematics/src/commands/change-theme/theme-options.enum.ts
@@ -0,0 +1,8 @@
+// this enum create by https://raw.githubusercontent.com/abpframework/abp/rel-6.0/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Theme.cs
+
+export enum ThemeOptionsEnum {
+ Basic = 1,
+ Lepton = 2,
+ LeptonXLite = 3,
+ LeptonX = 4,
+}
diff --git a/npm/ng-packs/scripts/build-schematics.ts b/npm/ng-packs/scripts/build-schematics.ts
index 8884ca9571..6690b272b3 100644
--- a/npm/ng-packs/scripts/build-schematics.ts
+++ b/npm/ng-packs/scripts/build-schematics.ts
@@ -21,6 +21,7 @@ class FileCopy {
const PACKAGE_TO_BUILD = 'schematics';
const FILES_TO_COPY_AFTER_BUILD: (FileCopy | string)[] = [
{ src: 'src/commands/create-lib/schema.json', dest: 'commands/create-lib/schema.json' },
+ { src: 'src/commands/change-theme/schema.json', dest: 'commands/change-theme/schema.json' },
{ src: 'src/commands/create-lib/files-package', dest: 'commands/create-lib/files-package' },
{
src: 'src/commands/create-lib/files-secondary-entrypoint',