Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .lint/.htmlhintrc
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
"title-require": true,
"alt-require": true,
"doctype-html5": true,
"id-class-value": "dash",
"id-class-value": false,
"style-disabled": true,
"inline-style-disabled": true,
"inline-script-disabled": true,
"space-tab-mixed-disabled": "space",
"id-class-ad-disabled": true,
"href-abs-or-rel": false,
"attr-unsafe-chars": true
}
}
10 changes: 3 additions & 7 deletions .lint/.stylelintrc.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
{
"extends": "stylelint-config-sass-guidelines",
"plugins": [
"stylelint-scss"
],
"plugins": ["stylelint-scss"],
"rules": {
"color-hex-length": "long",
"selector-pseudo-element-no-unknown": [
true,
{
"ignorePseudoElements": [
"ng-deep"
]
"ignorePseudoElements": ["ng-deep"]
}
]
}
}
}
2 changes: 1 addition & 1 deletion .lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"**/*.{ts,js}": "eslint --cache --fix",
"*": "prettier --cache --ignore-unknown --write"
}
}
5 changes: 5 additions & 0 deletions .postcssrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"plugins": {
"@tailwindcss/postcss": {}
}
}
8 changes: 6 additions & 2 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
package.json
package-lock.json
yarn
yarn.error.log
yarn.lock
yarn.error.log
.github/
.git/
.gitignore
.prettierignore
2 changes: 1 addition & 1 deletion .prettierrc: → .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"semi": true,
"singleQuote": true,
"bracketSpacing": true
}
}
2 changes: 1 addition & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"input": "public"
}
],
"styles": ["src/styles.scss"]
"styles": ["src/tailwind.css", "src/styles.scss"]
},
"configurations": {
"production": {
Expand Down
2 changes: 1 addition & 1 deletion commitlint.config.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = {extends: ['@commitlint/config-conventional']};
module.exports = { extends: ['@commitlint/config-conventional'] };
37 changes: 17 additions & 20 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// @ts-check
const eslint = require("@eslint/js");
const { defineConfig } = require("eslint/config");
const tseslint = require("typescript-eslint");
const angular = require("angular-eslint");
const eslint = require('@eslint/js');
const { defineConfig } = require('eslint/config');
const tseslint = require('typescript-eslint');
const angular = require('angular-eslint');

module.exports = defineConfig([
{
files: ["**/*.ts"],
files: ['**/*.ts'],
extends: [
eslint.configs.recommended,
tseslint.configs.recommended,
Expand All @@ -15,30 +15,27 @@ module.exports = defineConfig([
],
processor: angular.processInlineTemplates,
rules: {
"@angular-eslint/directive-selector": [
"error",
'@angular-eslint/directive-selector': [
'error',
{
type: "attribute",
prefix: "cai",
style: "camelCase",
type: 'attribute',
prefix: 'cai',
style: 'camelCase',
},
],
"@angular-eslint/component-selector": [
"error",
'@angular-eslint/component-selector': [
'error',
{
type: "element",
prefix: "cai",
style: "kebab-case",
type: 'element',
prefix: 'cai',
style: 'kebab-case',
},
],
},
},
{
files: ["**/*.html"],
extends: [
angular.configs.templateRecommended,
angular.configs.templateAccessibility,
],
files: ['**/*.html'],
extends: [angular.configs.templateRecommended, angular.configs.templateAccessibility],
rules: {},
},
]);
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@commitlint/config-conventional": "^21.0.0",
"@eslint/js": "^10.0.1",
"@ngx-env/builder": "^21.0.1",
"@tailwindcss/postcss": "^4",
"angular-eslint": "21.3.1",
"cross-env": "^10.1.0",
"eslint": "^10.0.3",
Expand All @@ -49,12 +50,14 @@
"json-server": "^1.0.0-beta.15",
"lint-staged": "^17.0.4",
"npm-run-all": "^4.1.5",
"postcss": "^8",
"prettier": "^3.8.3",
"stylelint": "^17.11.0",
"stylelint-config-sass-guidelines": "^13.0.0",
"stylelint-scss": "^7.0.0",
"tailwindcss": "^4",
"typescript": "~6.0.3",
"typescript-eslint": "8.56.1",
"typescript-eslint": "8.59.2",
"vitest": "^4.0.8"
}
}
26 changes: 11 additions & 15 deletions src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import {
ApplicationConfig,
importProvidersFrom,
provideBrowserGlobalErrorListeners,
} from "@angular/core";
import { provideRouter } from "@angular/router";
import { ApplicationConfig, importProvidersFrom, provideBrowserGlobalErrorListeners } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from "./app.routes";
import { provideTranslateHttpLoader } from "@ngx-translate/http-loader";
import { provideHttpClient } from "@angular/common/http";
import { provideTranslateService } from "@ngx-translate/core";
import { LoggerModule, NgxLoggerLevel } from "ngx-logger";
import { routes } from './app.routes';
import { provideTranslateHttpLoader } from '@ngx-translate/http-loader';
import { provideHttpClient } from '@angular/common/http';
import { provideTranslateService } from '@ngx-translate/core';
import { LoggerModule, NgxLoggerLevel } from 'ngx-logger';

export const appConfig: ApplicationConfig = {
providers: [
Expand All @@ -18,11 +14,11 @@ export const appConfig: ApplicationConfig = {
provideHttpClient(),
provideTranslateService({
loader: provideTranslateHttpLoader({
prefix: "/assets/i18n/",
suffix: ".json",
prefix: '/assets/i18n/',
suffix: '.json',
}),
fallbackLang: "en",
lang: import.meta.env.NG_APP_DEFAULT_LANGUAGE || "en",
fallbackLang: 'en',
lang: import.meta.env.NG_APP_DEFAULT_LANGUAGE || 'en',
}),
importProvidersFrom(LoggerModule.forRoot({ level: NgxLoggerLevel.INFO })),
],
Expand Down
10 changes: 9 additions & 1 deletion src/app/app.html
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
<h1>{{ 'app.hello' | translate }}</h1>
<div class="flex min-h-screen flex-col bg-[var(--background)] text-[var(--foreground)]">
<header class="flex items-center justify-between px-6 py-4 backdrop-blur">
<h1 class="text-base font-semibold tracking-tight">{{ 'app.hello' | translate }}</h1>
<cai-theme-toggle />
</header>
<main class="flex-1 px-6 py-8">
<router-outlet />
</main>
</div>
28 changes: 11 additions & 17 deletions src/app/app.spec.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,40 @@
import { TestBed } from "@angular/core/testing";
import { App } from "./app";
import {
TranslateLoader,
provideTranslateLoader,
provideTranslateService,
} from "@ngx-translate/core";
import { of } from "rxjs";
import en from "../../public/assets/i18n/en.json";
import { TestBed } from '@angular/core/testing';
import { App } from './app';
import { TranslateLoader, provideTranslateLoader, provideTranslateService } from '@ngx-translate/core';
import { of } from 'rxjs';
import en from '../../public/assets/i18n/en.json';

class TestTranslateLoader extends TranslateLoader {
getTranslation() {
return of(en);
}
}

describe("App", () => {
describe('App', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [App],
providers: [
provideTranslateService({
loader: provideTranslateLoader(TestTranslateLoader),
fallbackLang: "en",
lang: "en",
fallbackLang: 'en',
lang: 'en',
}),
],
}).compileComponents();
});

it("should create the app", () => {
it('should create the app', () => {
const fixture = TestBed.createComponent(App);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});

it("should render title", async () => {
it('should render title', async () => {
const fixture = TestBed.createComponent(App);
fixture.detectChanges();
await fixture.whenStable();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector("h1")?.textContent).toContain(
"Welcome to Cortex AI Dev Kit",
);
expect(compiled.querySelector('h1')?.textContent).toContain('Welcome to Cortex AI Dev Kit');
});
});
19 changes: 11 additions & 8 deletions src/app/app.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { Component, signal } from "@angular/core";
import { RouterOutlet } from "@angular/router";
import { TranslatePipe } from "@ngx-translate/core";
import { Component, inject, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { TranslatePipe } from '@ngx-translate/core';
import { ThemeService } from './core/theme/theme.service';
import { ThemeToggle } from './core/theme/theme-toggle';

@Component({
selector: "cai-root",
imports: [RouterOutlet, TranslatePipe],
templateUrl: "./app.html",
styleUrl: "./app.scss",
selector: 'cai-root',
imports: [RouterOutlet, TranslatePipe, ThemeToggle],
templateUrl: './app.html',
styleUrl: './app.scss',
})
export class App {
protected readonly title = signal("cortextaidevkit-ui");
protected readonly title = signal('cortextaidevkit-ui');
protected readonly theme = inject(ThemeService);
}
55 changes: 55 additions & 0 deletions src/app/core/theme/theme-toggle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
import { ThemeService } from './theme.service';

@Component({
selector: 'cai-theme-toggle',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<button
type="button"
(click)="theme.toggle()"
[attr.aria-label]="theme.isDark() ? 'Switch to light theme' : 'Switch to dark theme'"
[attr.aria-pressed]="theme.isDark()"
class="inline-flex h-9 w-9 items-center justify-center rounded-full border border-[var(--border)] bg-[var(--surface)] text-[var(--foreground)] transition-colors hover:bg-[var(--background)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--accent)]"
>
@if (theme.isDark()) {
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="h-4 w-4"
>
<circle cx="12" cy="12" r="4"></circle>
<path d="M12 2v2"></path>
<path d="M12 20v2"></path>
<path d="m4.93 4.93 1.41 1.41"></path>
<path d="m17.66 17.66 1.41 1.41"></path>
<path d="M2 12h2"></path>
<path d="M20 12h2"></path>
<path d="m6.34 17.66-1.41 1.41"></path>
<path d="m19.07 4.93-1.41 1.41"></path>
</svg>
} @else {
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="h-4 w-4"
>
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
</svg>
}
</button>
`,
})
export class ThemeToggle {
protected readonly theme = inject(ThemeService);
}
Loading