Răsfoiți Sursa

chore: base setup Tailwind and spartan-ui

David Höck 11 luni în urmă
părinte
comite
30502f2d24

+ 1 - 0
.nvmrc

@@ -0,0 +1 @@
+v20.16.0

Fișier diff suprimat deoarece este prea mare
+ 385 - 329
package-lock.json


+ 4 - 0
packages/admin-ui/components.json

@@ -0,0 +1,4 @@
+
+{
+  "componentsPath": "src/lib/ui"
+}

+ 118 - 117
packages/admin-ui/package.json

@@ -1,120 +1,121 @@
 {
-    "name": "@vendure/admin-ui",
-    "version": "3.1.2",
-    "license": "GPL-3.0-or-later",
-    "scripts": {
-        "ng": "ng",
-        "dev": "node scripts/set-version.js && ng serve",
-        "build:app": "ng build vendure-admin --configuration production",
-        "build": "node scripts/copy-package-json.js && node scripts/set-version.js && node scripts/build-public-api.js && ng build vendure-admin-lib --configuration production && node scripts/compile-styles.js",
-        "watch": "ng build --watch=true",
-        "test": "ng test --watch=false --browsers=ChromeHeadlessCI --progress=false",
-        "lint": "ng lint --fix",
-        "extract-translations": "node scripts/extract-translations.js",
-        "ngcc": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points"
-    },
-    "homepage": "https://www.vendure.io/",
-    "funding": "https://github.com/sponsors/michaelbromley",
-    "publishConfig": {
-        "access": "public",
-        "directory": "package"
-    },
-    "//": "These exports are just here so that we can do local testing of ui-devkit compilation by allowing the ui-devkit package to find its way to the compiled package",
-    "exports": {
-        ".": {
-            "types": "./package/index.d.ts",
-            "esm2022": "./package/esm2022/vendure-admin-ui.mjs",
-            "esm": "./package/esm2022/vendure-admin-ui.mjs",
-            "default": "./package/fesm2022/vendure-admin-ui.mjs"
-        }
-    },
-    "dependencies": {
-        "@angular/animations": "^17.2.4",
-        "@angular/cdk": "^17.2.2",
-        "@angular/common": "^17.2.4",
-        "@angular/core": "^17.2.4",
-        "@angular/forms": "^17.2.4",
-        "@angular/language-service": "^17.2.4",
-        "@angular/platform-browser": "^17.2.4",
-        "@angular/platform-browser-dynamic": "^17.2.4",
-        "@angular/router": "^17.2.4",
-        "@apollo/client": "^3.9.6",
-        "@biesbjerg/ngx-translate-extract-marker": "^1.0.0",
-        "@cds/core": "^6.9.2",
-        "@clr/angular": "^17.0.1",
-        "@clr/core": "^4.0.15",
-        "@clr/icons": "^13.0.2",
-        "@clr/ui": "^17.0.1",
-        "@messageformat/core": "^3.2.0",
-        "@ng-select/ng-select": "^12.0.7",
-        "@ngx-translate/core": "^15.0.0",
-        "@ngx-translate/http-loader": "^8.0.0",
-        "@vendure/common": "^3.1.2",
-        "@webcomponents/custom-elements": "^1.6.0",
-        "apollo-angular": "^6.0.0",
-        "apollo-upload-client": "^18.0.1",
-        "chartist": "^1.3.0",
-        "codejar": "^4.2.0",
-        "dayjs": "^1.11.10",
-        "graphql": "~16.9.0",
-        "just-extend": "^6.2.0",
-        "messageformat": "2.3.0",
-        "ngx-pagination": "^6.0.3",
-        "ngx-translate-messageformat-compiler": "^6.5.0",
-        "prosemirror-commands": "^1.5.2",
-        "prosemirror-dropcursor": "^1.8.1",
-        "prosemirror-gapcursor": "^1.3.2",
-        "prosemirror-history": "^1.3.2",
-        "prosemirror-inputrules": "^1.4.0",
-        "prosemirror-keymap": "^1.2.2",
-        "prosemirror-menu": "^1.2.4",
-        "prosemirror-schema-basic": "^1.2.2",
-        "prosemirror-schema-list": "^1.3.0",
-        "prosemirror-state": "^1.4.3",
-        "prosemirror-tables": "^1.3.7",
-        "react": "^18.2.0",
-        "react-dom": "^18.2.0",
-        "rxjs": "^7.8.1",
-        "tslib": "^2.6.2",
-        "zone.js": "~0.14.4"
-    },
-    "devDependencies": {
-        "@angular-devkit/build-angular": "^17.2.3",
-        "@angular-eslint/builder": "^17.2.1",
-        "@angular-eslint/eslint-plugin": "^17.2.1",
-        "@angular-eslint/eslint-plugin-template": "^17.2.1",
-        "@angular-eslint/schematics": "^17.2.1",
-        "@angular-eslint/template-parser": "^17.2.1",
-        "@angular/cli": "^17.2.3",
-        "@angular/compiler": "^17.2.4",
-        "@angular/compiler-cli": "^17.2.4",
-        "@types/jasmine": "~4.3.5",
-        "@types/jasminewd2": "~2.0.10",
-        "@types/node": "^18.17.9",
-        "@types/react": "^18.2.21",
-        "@typescript-eslint/eslint-plugin": "^5.59.2",
-        "@typescript-eslint/parser": "^5.59.2",
-        "@vendure/ngx-translate-extract": "^8.2.2",
-        "autoprefixer": "^10.4.19",
-        "cross-spawn": "^7.0.3",
-        "eslint": "^8.41.0",
-        "eslint-plugin-import": "^2.27.5",
-        "eslint-plugin-jsdoc": "^45.0.0",
-        "eslint-plugin-prefer-arrow": "^1.2.3",
-        "fs-extra": "^11.2.0",
-        "jasmine-core": "~3.99.1",
-        "jasmine-spec-reporter": "~7.0.0",
-        "karma": "~6.3.4",
-        "karma-chrome-launcher": "~3.1.0",
-        "karma-coverage-istanbul-reporter": "~3.0.2",
-        "karma-jasmine": "~4.0.0",
-        "karma-jasmine-html-reporter": "^1.7.0",
-        "karma-mocha-reporter": "^2.2.5",
-        "ng-packagr": "17.2.1",
-        "postcss": "^8.4.38",
-        "puppeteer": "^19.8.3",
-        "rimraf": "^5.0.5",
-        "tailwindcss": "^3.4.3",
-        "typescript": "5.3.3"
+  "name": "@vendure/admin-ui",
+  "version": "3.1.2",
+  "license": "GPL-3.0-or-later",
+  "scripts": {
+    "ng": "ng",
+    "dev": "node scripts/set-version.js && ng serve",
+    "build:app": "ng build vendure-admin --configuration production",
+    "build": "node scripts/copy-package-json.js && node scripts/set-version.js && node scripts/build-public-api.js && ng build vendure-admin-lib --configuration production && node scripts/compile-styles.js",
+    "watch": "ng build --watch=true",
+    "test": "ng test --watch=false --browsers=ChromeHeadlessCI --progress=false",
+    "lint": "ng lint --fix",
+    "extract-translations": "node scripts/extract-translations.js",
+    "ngcc": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points"
+  },
+  "homepage": "https://www.vendure.io/",
+  "funding": "https://github.com/sponsors/michaelbromley",
+  "publishConfig": {
+    "access": "public",
+    "directory": "package"
+  },
+  "//": "These exports are just here so that we can do local testing of ui-devkit compilation by allowing the ui-devkit package to find its way to the compiled package",
+  "exports": {
+    ".": {
+      "types": "./package/index.d.ts",
+      "esm2022": "./package/esm2022/vendure-admin-ui.mjs",
+      "esm": "./package/esm2022/vendure-admin-ui.mjs",
+      "default": "./package/fesm2022/vendure-admin-ui.mjs"
     }
+  },
+  "dependencies": {
+    "@angular/animations": "^18.2.13",
+    "@angular/cdk": "^18.2.13",
+    "@angular/common": "^18.2.13",
+    "@angular/core": "^18.2.13",
+    "@angular/forms": "^18.2.13",
+    "@angular/language-service": "^18.2.13",
+    "@angular/platform-browser": "^18.2.13",
+    "@angular/platform-browser-dynamic": "^18.2.13",
+    "@angular/router": "^18.2.13",
+    "@apollo/client": "^3.9.6",
+    "@biesbjerg/ngx-translate-extract-marker": "^1.0.0",
+    "@messageformat/core": "^3.2.0",
+    "@ng-icons/core": "^29.10.0",
+    "@ng-select/ng-select": "^12.0.7",
+    "@ngx-translate/core": "^15.0.0",
+    "@ngx-translate/http-loader": "^8.0.0",
+    "@spartan-ng/brain": "0.0.1-alpha.381",
+    "@spartan-ng/ui-core": "latest",
+    "@vendure/common": "^3.1.2",
+    "@webcomponents/custom-elements": "^1.6.0",
+    "apollo-angular": "^6.0.0",
+    "apollo-upload-client": "^18.0.1",
+    "chartist": "^1.3.0",
+    "codejar": "^4.2.0",
+    "dayjs": "^1.11.10",
+    "graphql": "~16.9.0",
+    "just-extend": "^6.2.0",
+    "messageformat": "2.3.0",
+    "ngx-pagination": "^6.0.3",
+    "ngx-translate-messageformat-compiler": "^6.5.0",
+    "prosemirror-commands": "^1.5.2",
+    "prosemirror-dropcursor": "^1.8.1",
+    "prosemirror-gapcursor": "^1.3.2",
+    "prosemirror-history": "^1.3.2",
+    "prosemirror-inputrules": "^1.4.0",
+    "prosemirror-keymap": "^1.2.2",
+    "prosemirror-menu": "^1.2.4",
+    "prosemirror-schema-basic": "^1.2.2",
+    "prosemirror-schema-list": "^1.3.0",
+    "prosemirror-state": "^1.4.3",
+    "prosemirror-tables": "^1.3.7",
+    "react": "^18.2.0",
+    "react-dom": "^18.2.0",
+    "rxjs": "^7.8.1",
+    "tslib": "^2.6.2",
+    "zone.js": "~0.14.4"
+  },
+  "devDependencies": {
+    "@angular-devkit/build-angular": "^18.2.14",
+    "@angular-eslint/builder": "^18.2.14",
+    "@angular-eslint/eslint-plugin": "^18.2.14",
+    "@angular-eslint/eslint-plugin-template": "^18.2.14",
+    "@angular-eslint/schematics": "^18.2.14",
+    "@angular-eslint/template-parser": "^18.2.14",
+    "@angular/cli": "^18.2.14",
+    "@angular/compiler": "^18.2.13",
+    "@angular/compiler-cli": "^18.2.13",
+    "@spartan-ng/cli": "latest",
+    "@types/jasmine": "~4.3.5",
+    "@types/jasminewd2": "~2.0.10",
+    "@types/node": "^18.17.9",
+    "@types/react": "^18.2.21",
+    "@typescript-eslint/eslint-plugin": "^5.59.2",
+    "@typescript-eslint/parser": "^5.59.2",
+    "@vendure/ngx-translate-extract": "^8.2.2",
+    "autoprefixer": "^10.4.19",
+    "cross-spawn": "^7.0.5",
+    "eslint": "^8.41.0",
+    "eslint-plugin-import": "^2.27.5",
+    "eslint-plugin-jsdoc": "^45.0.0",
+    "eslint-plugin-prefer-arrow": "^1.2.3",
+    "fs-extra": "^11.2.0",
+    "jasmine-core": "~3.99.1",
+    "jasmine-spec-reporter": "~7.0.0",
+    "karma": "~6.3.4",
+    "karma-chrome-launcher": "~3.1.0",
+    "karma-coverage-istanbul-reporter": "~3.0.2",
+    "karma-jasmine": "~4.0.0",
+    "karma-jasmine-html-reporter": "^1.7.0",
+    "karma-mocha-reporter": "^2.2.5",
+    "ng-packagr": "^18.2.1",
+    "postcss": "^8.4.38",
+    "puppeteer": "^19.8.3",
+    "rimraf": "^5.0.5",
+    "tailwind-merge": "^2.2.0",
+    "tailwindcss": "^3.4.3",
+    "tailwindcss-animate": "^1.0.6",
+    "typescript": "5.4.5"
+  }
 }

+ 1 - 1
packages/admin-ui/src/lib/catalog/src/components/collection-data-table/collection-data-table.component.html

@@ -38,7 +38,7 @@
                         </vdr-ui-extension-point>
                         <div *ngIf="column.sort as sort" class="sort-toggle">
                             <button (click)="sort.toggleSortOrder()" [class.active]="sort.sortOrder">
-                                <clr-icon *ngIf="!sort.sortOrder" shape="two-way-arrows left"></clr-icon>
+                                <hlm *ngIf="!sort.sortOrder" shape="two-way-arrows left"></hlm>
                                 <clr-icon *ngIf="sort.sortOrder === 'ASC'" shape="arrow up"></clr-icon>
                                 <clr-icon *ngIf="sort.sortOrder === 'DESC'" shape="arrow down"></clr-icon>
                             </button>

+ 2 - 4
packages/admin-ui/src/lib/core/src/shared/shared.module.ts

@@ -5,9 +5,6 @@ import { CommonModule } from '@angular/common';
 import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
 import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 import { RouterModule } from '@angular/router';
-import { ClarityModule } from '@clr/angular';
-import '@clr/icons';
-import '@clr/icons/shapes/all-shapes';
 import { NgSelectModule } from '@ng-select/ng-select';
 import { TranslateModule } from '@ngx-translate/core';
 import '@webcomponents/custom-elements/custom-elements.min.js';
@@ -177,9 +174,9 @@ import { AddFilterPresetButtonComponent } from './components/data-table-filter-p
 import { RenameFilterPresetDialogComponent } from './components/data-table-filter-presets/rename-filter-preset-dialog.component';
 import { ActionBarDropdownMenuComponent } from './components/action-bar-dropdown-menu/action-bar-dropdown-menu.component';
 import { DuplicateEntityDialogComponent } from './components/duplicate-entity-dialog/duplicate-entity-dialog.component';
+import { HlmIconModule } from '@spartan-ng/ui-icon-helm';
 
 const IMPORTS = [
-    ClarityModule,
     CommonModule,
     FormsModule,
     ReactiveFormsModule,
@@ -190,6 +187,7 @@ const IMPORTS = [
     OverlayModule,
     DragDropModule,
     A11yModule,
+    HlmIconModule,
 ];
 
 const DECLARATIONS = [

+ 21 - 18
packages/admin-ui/src/lib/login/src/components/login/login.component.html

@@ -1,21 +1,7 @@
-<div class="flex h-screen justify-center items-center bg-slate-100" [dir]="direction$ | async">
-    <div class="rounded-lg overflow-hidden w-[1120px] h-[590px] flex bg-white items-start relative justify-start border border-slate-200 shadow-lg hover:shadow-2xl transition-all">
-        <div class="relative h-full grow">
-            <div class="absolute p-10 left-0 bottom-0 w-full z-20 text-white bg-gradient-to-b from-black/0 to-black/50">
-                <div class="text-2xl text-white font-bold">
-                    {{ 'common.login-image-title' | translate }}
-                </div>
-                <div class="text-sm text-white/80">
-                    <p *ngIf="imageCreator" class="creator">
-                        Photo by <a [href]="imageCreatorUrl" target="_blank">{{ imageCreator }}</a> on
-                        <a [href]="imageUnsplashUrl" target="_blank">Unsplash</a>
-                    </p>
-                    <p *ngIf="imageLocation" class="location">{{ imageLocation }}</p>
-                </div>
-            </div>
-            <img class="absolute z-10 left-0 right-0 h-full w-full object-cover object-center top-0 bottom-0" *ngIf="imageUrl" [src]="imageUrl" [alt]="imageUrl" />
-        </div>
-        <div class="flex h-full p-10 flex-col items-stretch justify-center min-w-[400px]">
+<div class="grid grid-cols-2 h-dvh w-full bg-neutral-100" [dir]="direction$ | async">
+    <!-- Form Area -->
+    <div class="h-full flex flex-col items-center justify-center">
+        <div class="flex p-10 flex-col items-stretch justify-center max-w-[400px]">
             <p class="text-2xl text-slate-800 font-bold mb-4">
                 {{ 'common.login-title' | translate : { brand: hideVendureBranding ? brand : 'Vendure' } }}
             </p>
@@ -74,4 +60,21 @@
         </div>
         <img class="absolute right-5 top-5 h-16 " src="assets/logo-login.webp" *ngIf="!hideVendureBranding" />
     </div>
+
+    <!-- Image Area -->
+    <div class="h-full p-8">
+        <div class="rounded-md overflow-hidden relative h-full">
+            <div class="absolute bottom-10 left-10">
+                <p *ngIf="imageCreator" class="text-lg font-semibold text-white">
+                    Photo by <a [href]="imageCreatorUrl" class="underline" target="_blank">{{ imageCreator }}</a> on
+                    <a [href]="imageUnsplashUrl" class="underline" target="_blank">Unsplash</a>
+                </p>
+                <span *ngIf="imageLocation" class="text-md text-white/80">{{ imageLocation }}</span>
+            </div>
+            <img class="left-0 right-0 bottom-0 h-full w-full object-cover object-center top-0"
+                 *ngIf="imageUrl" [src]="imageUrl" [alt]="imageUrl" />
+        </div>
+    </div>
+
+
 </div>

+ 0 - 2
packages/admin-ui/src/lib/static/styles/_variables.scss

@@ -1,6 +1,4 @@
 @import "./global/sass-overrides";
-@import "@clr/ui/src/utils/_mixins";
-@import "@clr/ui/src/utils/_variables.clarity.scss";
 
 // breakpoints
 // Breakpoints are defined in SCSS because CSS does not

+ 0 - 2
packages/admin-ui/src/lib/static/styles/styles.scss

@@ -3,8 +3,6 @@
 @tailwind utilities;
 
 @import 'global/sass-overrides';
-@import 'global/clarity';
-@import '@clr/icons/clr-icons.min.css';
 @import '@ng-select/ng-select/themes/default.theme.css';
 @import '@angular/cdk/overlay-prebuilt.css';
 @import 'global/buttons';

+ 11 - 0
packages/admin-ui/src/lib/ui/ui-icon-helm/src/index.ts

@@ -0,0 +1,11 @@
+import { NgModule } from '@angular/core';
+import { HlmIconDirective } from './lib/hlm-icon.directive';
+
+export * from './lib/hlm-icon.directive';
+export * from './lib/hlm-icon.token';
+
+@NgModule({
+	imports: [HlmIconDirective],
+	exports: [HlmIconDirective],
+})
+export class HlmIconModule {}

+ 66 - 0
packages/admin-ui/src/lib/ui/ui-icon-helm/src/lib/hlm-icon.directive.spec.ts

@@ -0,0 +1,66 @@
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
+import { By } from '@angular/platform-browser';
+import { NgIcon, provideIcons } from '@ng-icons/core';
+import { lucideCheck } from '@ng-icons/lucide';
+import { type RenderResult, render } from '@testing-library/angular';
+import { HlmIconDirective } from './hlm-icon.directive';
+
+@Component({
+	selector: 'hlm-mock',
+	standalone: true,
+	changeDetection: ChangeDetectionStrategy.OnPush,
+	imports: [HlmIconDirective, NgIcon],
+	providers: [provideIcons({ lucideCheck })],
+	template: `
+		<ng-icon hlm class="test" name="lucideCheck" [size]="size" color="red" strokeWidth="2" />
+	`,
+})
+class HlmMockComponent {
+	@Input() public size = 'base';
+}
+
+describe('HlmIconDirective', () => {
+	let r: RenderResult<HlmMockComponent>;
+	let icon: HTMLElement;
+
+	beforeEach(async () => {
+		r = await render(HlmMockComponent);
+		icon = r.container.querySelector('ng-icon')!;
+	});
+
+	it('should add the xs size', async () => {
+		await r.rerender({ componentInputs: { size: 'xs' } });
+		r.fixture.detectChanges();
+		expect(icon.getAttribute('style')).toContain('--ng-icon__size: 12px');
+	});
+
+	it('should add the sm size', async () => {
+		await r.rerender({ componentInputs: { size: 'sm' } });
+		r.fixture.detectChanges();
+		expect(icon.getAttribute('style')).toContain('--ng-icon__size: 16px');
+	});
+
+	it('should add the base size', () => {
+		expect(icon.getAttribute('style')).toContain('--ng-icon__size: 24px');
+	});
+
+	it('should add the lg size', async () => {
+		await r.rerender({ componentInputs: { size: 'lg' } });
+		r.fixture.detectChanges();
+		expect(icon.getAttribute('style')).toContain('--ng-icon__size: 32px');
+	});
+
+	it('should add the xl size', async () => {
+		await r.rerender({ componentInputs: { size: 'xl' } });
+		r.fixture.detectChanges();
+		expect(icon.getAttribute('style')).toContain('--ng-icon__size: 48px');
+	});
+
+	it('should forward the size property if the size is not a pre-defined size', async () => {
+		await r.rerender({ componentInputs: { size: '2rem' } });
+		r.fixture.detectChanges();
+		const debugEl = r.fixture.debugElement.query(By.directive(NgIcon));
+		expect(debugEl.componentInstance.size()).toBe('2rem');
+		expect(icon.getAttribute('style')).toContain('--ng-icon__size: 2rem');
+	});
+});

+ 36 - 0
packages/admin-ui/src/lib/ui/ui-icon-helm/src/lib/hlm-icon.directive.ts

@@ -0,0 +1,36 @@
+import { Directive, computed, input } from '@angular/core';
+import { injectHlmIconConfig } from './hlm-icon.token';
+
+export type IconSize = 'xs' | 'sm' | 'base' | 'lg' | 'xl' | 'none' | (Record<never, never> & string);
+
+@Directive({
+	selector: 'ng-icon[hlm]',
+	standalone: true,
+	host: {
+		'[style.--ng-icon__size]': '_computedSize()',
+	},
+})
+export class HlmIconDirective {
+	private readonly _config = injectHlmIconConfig();
+	public readonly size = input<IconSize>(this._config.size);
+
+	protected readonly _computedSize = computed(() => {
+		const size = this.size();
+
+		switch (size) {
+			case 'xs':
+				return '12px';
+			case 'sm':
+				return '16px';
+			case 'base':
+				return '24px';
+			case 'lg':
+				return '32px';
+			case 'xl':
+				return '48px';
+			default: {
+				return size;
+			}
+		}
+	});
+}

+ 20 - 0
packages/admin-ui/src/lib/ui/ui-icon-helm/src/lib/hlm-icon.token.ts

@@ -0,0 +1,20 @@
+import { InjectionToken, ValueProvider, inject } from '@angular/core';
+import type { IconSize } from './hlm-icon.directive';
+
+export interface HlmIconConfig {
+	size: IconSize;
+}
+
+const defaultConfig: HlmIconConfig = {
+	size: 'base',
+};
+
+const HlmIconConfigToken = new InjectionToken<HlmIconConfig>('HlmIconConfig');
+
+export function provideHlmIconConfig(config: Partial<HlmIconConfig>): ValueProvider {
+	return { provide: HlmIconConfigToken, useValue: { ...defaultConfig, ...config } };
+}
+
+export function injectHlmIconConfig(): HlmIconConfig {
+	return inject(HlmIconConfigToken, { optional: true }) ?? defaultConfig;
+}

+ 1 - 0
packages/admin-ui/tailwind.config.js

@@ -3,6 +3,7 @@ const defaultTheme = require('tailwindcss/defaultTheme');
 
 /** @type {import('tailwindcss').Config} */
 module.exports = {
+    presets: [require('@spartan-ng/ui-core/hlm-tailwind-preset')],
     content: ['./src/**/*.{html,ts}'],
     theme: {
         colors: {

+ 3 - 0
packages/admin-ui/tsconfig.json

@@ -59,6 +59,9 @@
       ],
       "@vendure/admin-ui/system": [
         "./src/lib/system/src/public_api"
+      ],
+      "@spartan-ng/ui-icon-helm": [
+        "./src/lib/ui/ui-icon-helm/src/index.ts"
       ]
     },
     "useDefineForClassFields": false

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff