From 678ce12de4fb9921c03df563a207db2f3963aa13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sieciechowicz?= Date: Sat, 2 Aug 2025 18:55:34 +0200 Subject: [PATCH] add components --- .gitignore | 1 + .npmignore | 31 ++ LICENSE | 55 +++ README-THEME-INTEGRATION.md | 124 ++++++ README.md | 357 +++++++++++++----- package.json | 39 +- .../components/button/button.component.html | 1 + .../components/button/button.component.scss | 12 + src/lib/components/button/button.component.ts | 11 + src/lib/components/card/card.component.html | 1 + src/lib/components/card/card.component.scss | 0 .../components/card/card.component.spec.ts | 23 ++ src/lib/components/card/card.component.ts | 11 + .../components/input/input.component.html | 1 + .../components/input/input.component.scss | 0 .../components/input/input.component.spec.ts | 23 ++ .../form/components/input/input.component.ts | 11 + src/lib/modules/form/form-module.ts | 12 + .../components/content/content.component.scss | 6 +- .../components/header/header.component.html | 3 + .../components/header/header.component.scss | 18 + .../header/header.component.spec.ts | 23 ++ .../components/header/header.component.ts | 13 + .../menu-item/menu-item.component.scss | 22 +- .../components/menu/menu.component.scss | 4 +- src/lib/modules/layout/layout-module.ts | 3 + src/lib/styles/_theme-mixins.scss | 86 +++++ src/lib/styles/integration-example.scss | 43 +++ src/lib/styles/ui-themes.scss | 4 + src/public-api.ts | 9 +- 30 files changed, 804 insertions(+), 143 deletions(-) create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 LICENSE create mode 100644 README-THEME-INTEGRATION.md create mode 100644 src/lib/components/button/button.component.html create mode 100644 src/lib/components/button/button.component.scss create mode 100644 src/lib/components/button/button.component.ts create mode 100644 src/lib/components/card/card.component.html create mode 100644 src/lib/components/card/card.component.scss create mode 100644 src/lib/components/card/card.component.spec.ts create mode 100644 src/lib/components/card/card.component.ts create mode 100644 src/lib/modules/form/components/input/input.component.html create mode 100644 src/lib/modules/form/components/input/input.component.scss create mode 100644 src/lib/modules/form/components/input/input.component.spec.ts create mode 100644 src/lib/modules/form/components/input/input.component.ts create mode 100644 src/lib/modules/form/form-module.ts create mode 100644 src/lib/modules/layout/components/header/header.component.html create mode 100644 src/lib/modules/layout/components/header/header.component.scss create mode 100644 src/lib/modules/layout/components/header/header.component.spec.ts create mode 100644 src/lib/modules/layout/components/header/header.component.ts create mode 100644 src/lib/styles/_theme-mixins.scss create mode 100644 src/lib/styles/integration-example.scss create mode 100644 src/lib/styles/ui-themes.scss diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..06cf653 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +cache diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..42e753f --- /dev/null +++ b/.npmignore @@ -0,0 +1,31 @@ +# Source files +src/ +*.ts +!*.d.ts + +# Development files +tsconfig.*.json +ng-package.json +karma.conf.js +*.spec.ts + +# Build files +node_modules/ +coverage/ +.nyc_output/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a01f722 --- /dev/null +++ b/LICENSE @@ -0,0 +1,55 @@ +Workshack UI Library License + +Copyright (c) 2025 Workshack Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to use, +copy, modify, merge, publish, and distribute the Software, subject to the +following conditions: + +NON-COMMERCIAL USE: +For non-commercial applications (applications that do not generate revenue, +do not contain paid features, subscriptions, advertisements, or any form of +monetization), the Software may be used freely without any additional +requirements. + +COMMERCIAL USE: +For commercial applications (applications that generate revenue through sales, +subscriptions, advertisements, in-app purchases, or any other form of +monetization), the following additional requirement applies: + +- The application MUST include attribution to the Workshack UI Library in a + publicly accessible location within the application. This can be: + * An "About" page or section + * A "Credits" or "Acknowledgments" page + * A "For Developers" page + * Any other location where users can reasonably find it + +The attribution must include: +- The name "Workshack UI Library" +- A link to the library's repository or npm package page +- The copyright notice "© 2025 Workshack Team" + +Example attribution: +"This application uses Workshack UI Library (https://www.npmjs.com/package/@workshack/ui) © 2025 Workshack Team" + +GENERAL CONDITIONS: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +DEFINITIONS: +- "Commercial application" means any software application, website, or service + that generates revenue or is intended to generate revenue through any means + including but not limited to: sales, subscriptions, advertisements, in-app + purchases, premium features, or commercial licensing. +- "Non-commercial application" means any software application, website, or + service that is provided free of charge with no revenue generation or + monetization of any kind. diff --git a/README-THEME-INTEGRATION.md b/README-THEME-INTEGRATION.md new file mode 100644 index 0000000..d3745f3 --- /dev/null +++ b/README-THEME-INTEGRATION.md @@ -0,0 +1,124 @@ +# UI Library Theme Integration + +## Przegląd + +Biblioteka UI została przeprojektowana jako niezależna biblioteka z własnym systemem zmiennych CSS. Główna aplikacja generuje zmienne UI dla każdego motywu, zapewniając pełną integrację przy zachowaniu przenośności biblioteki. + +## Jak to działa + +### 1. Niezależne zmienne CSS + +Komponenty UI używają tylko własnych zmiennych CSS z hardcoded fallbackami: + +```scss +background: var(--ui-color-menu-bg, #343a40); +``` + +**Kolejność fallbacków:** +1. `--ui-color-menu-bg` - zmienna UI generowana przez główną aplikację +2. `#343a40` - hardcoded fallback dla przenośności + +### 2. Automatyczna integracja + +Mixiny w `_theme-mixins.scss` generują zmienne UI dla każdego motywu: + +```scss +html[theme="default-light"] { + --ui-color-menu-bg: var(--color-bg-dark); + --ui-color-menu-text: var(--color-text-white); + --ui-color-menu-hover: var(--color-hover-bg); + // ... inne zmienne +} +``` + +## Dostępne zmienne UI + +### Kolory menu +- `--ui-color-menu-bg` - tło menu +- `--ui-color-menu-text` - tekst menu +- `--ui-color-menu-hover` - hover menu +- `--ui-color-menu-active` - aktywny element menu +- `--ui-color-menu-border` - obramowanie menu + +### Kolory zawartości +- `--ui-color-content-bg` - tło obszaru zawartości +- `--ui-color-content-text` - tekst zawartości + +### Kolory ikon +- `--ui-color-icon-primary` - ikony podstawowe +- `--ui-color-icon-secondary` - ikony drugorzędne +- `--ui-color-icon-muted` - ikony wyciszone + +## Komponenty z integracją motywów + +### ✅ Zintegrowane komponenty: +- `MenuComponent` - menu boczne z automatycznym dostosowaniem kolorów +- `MenuItemComponent` - elementy menu z hover states +- `ContentComponent` - obszar zawartości z theme-aware tłem +- `IconComponent` - ikony z kolorami z motywu + +### 📋 Struktura komponentów: + +```scss +:host { + // Podstawowe style layoutu + display: flex; + + // Theme-aware kolory z fallbackami + background: var(--ui-color-menu-bg, var(--color-bg-dark, #343a40)); + color: var(--ui-color-menu-text, var(--color-text-white, #ffffff)); + + // Hover states + &:hover { + background: var(--ui-color-menu-hover, var(--color-hover-bg, rgba(255, 255, 255, 0.1))); + } +} +``` + +## Obsługiwane motywy + +Biblioteka UI automatycznie dostosowuje się do wszystkich motywów głównej aplikacji: + +- ✅ `system` - automatyczne wykrywanie preferencji systemowych +- ✅ `default-light` - jasny motyw domyślny +- ✅ `default-dark` - ciemny motyw z niebieskimi akcentami +- ✅ `monochrome-light` - monochromatyczny jasny +- ✅ `monochrome-dark` - monochromatyczny ciemny + +## Dodawanie nowych komponentów + +Przy tworzeniu nowych komponentów UI, używaj zmiennych CSS z fallbackami: + +```scss +.new-component { + background: var(--ui-color-primary, var(--color-primary, #2c3e50)); + color: var(--ui-color-text, var(--color-text-white, #ffffff)); + border: 1px solid var(--ui-color-border, var(--color-border, #e0e0e0)); +} +``` + +## Customizacja + +Jeśli potrzebujesz różnych kolorów dla UI niż w głównej aplikacji, możesz nadpisać zmienne UI: + +```scss +html[theme="custom"] { + --ui-color-menu-bg: #your-custom-color; + --ui-color-menu-text: #your-text-color; +} +``` + +## Zalety tego podejścia + +1. **Automatyczna synchronizacja** - UI automatycznie dostosowuje się do zmian motywu +2. **Fallbacki** - komponenty działają nawet bez systemu motywów +3. **Elastyczność** - możliwość customizacji kolorów UI niezależnie od głównej aplikacji +4. **Wydajność** - brak potrzeby rekompilacji przy zmianie motywu +5. **Spójność** - wszystkie komponenty UI używają tych samych zmiennych + +## Pliki systemu + +- `packages/ui/src/lib/styles/_theme-mixins.scss` - mixiny do generowania zmiennych +- `packages/ui/src/lib/styles/ui-themes.scss` - główny plik integracji +- `src/styles.scss` - import integracji w głównej aplikacji +- `src/themes.scss` - system motywów głównej aplikacji diff --git a/README.md b/README.md index 5968a84..69f59c8 100644 --- a/README.md +++ b/README.md @@ -1,155 +1,304 @@ -# @ngshack/ui +# @workshack/ui -Webland UI component library for Angular applications with gaming console theme. +Workshack UI component library for Angular applications with layout and navigation components. ## Installation ```bash -npm install @ngshack/ui +npm install @workshack/ui ``` -## Development +## Components -### Prerequisites -- Node.js 18+ -- Angular CLI 17+ +### LayoutModule -### Setup -```bash -npm install -``` - -### Generate Components -```bash -# Generate new component -ng generate component components/my-component --project=ui - -# Generate service -ng generate service services/my-service --project=ui - -# Generate module -ng generate module modules/my-module --project=ui -``` - -### Build Library -```bash -ng build ui -``` - -### Test -```bash -ng test ui -``` - -### Publish -```bash -npm run build:libs -npm publish dist/ui -``` - -## Usage - -### Button Component +Import the complete layout module to get access to all layout components: ```typescript -import { ButtonComponent } from '@ngshack/ui'; +import { LayoutModule } from '@workshack/ui'; @Component({ - imports: [ButtonComponent], + imports: [LayoutModule], template: ` - Click me - Large Button - Disabled + + + + + + + + + + + + ` }) -export class MyComponent {} +export class AppComponent {} ``` -#### Properties -- `variant`: 'primary' | 'secondary' | 'outline' (default: 'primary') -- `size`: 'sm' | 'md' | 'lg' (default: 'md') -- `disabled`: boolean (default: false) -- `type`: 'button' | 'submit' | 'reset' (default: 'button') +### Layout Components -### Card Component +#### LayoutComponent (``) + +**Selector:** `ui-layout` +**Description:** Root container component that provides the main layout structure. + +**Usage:** +```html + + + +``` + +**Properties:** None +**Content Projection:** Accepts any content, typically `ui-menu` and `ui-content` + +--- + +#### MenuComponent (``) + +**Selector:** `ui-menu` +**Description:** Vertical sidebar menu container for navigation items. + +**Usage:** +```html + + + + +``` + +**Properties:** None +**Content Projection:** Accepts `ui-menu-item` components +**Styling:** +- Width: 4rem +- Background: `var(--ui-color-menu-bg, #343a40)` +- Color: `var(--ui-color-menu-text, #ffffff)` + +--- + +#### MenuItemComponent (``) + +**Selector:** `ui-menu-item` +**Description:** Individual menu item with icon and label. + +**Usage:** +```html + + +``` + +**Properties:** +- `label: string` (required) - Text label displayed below the icon +- `icon: string` (required) - Icon name (uses RemixIcon classes) + +**Styling:** +- Size: 4rem × 4rem +- Hover effect: `rgba(255, 255, 255, 0.1)` background +- Active state: `#2c2c2c` background +- Icon size: 1.7rem +- Label size: 0.6rem + +--- + +#### ContentComponent (``) + +**Selector:** `ui-content` +**Description:** Main content area container. + +**Usage:** +```html + + + + +``` + +**Properties:** None +**Content Projection:** Accepts any content, typically starts with `ui-header` + +--- + +#### HeaderComponent (``) + +**Selector:** `ui-header` +**Description:** Page header with title and action buttons. + +**Usage:** +```html + + + + +``` + +**Properties:** +- `label: string` - Page title displayed in the header + +**Content Projection:** Right-aligned action buttons or other controls +**Styling:** +- Padding: 0.6rem +- Background: `var(--ui-color-menu-bg, #343a40)` +- Color: `var(--ui-color-menu-text, #ffffff)` +- Title font size: 1.4rem +- Title transform: capitalize + +--- + +### IconComponent (Directive) + +**Selector:** `[uiIcon]` +**Description:** Directive for displaying RemixIcon icons. + +**Usage:** +```html + + +``` + +**Properties:** +- `uiIcon: string` - Icon name (RemixIcon class name without 'ri-' prefix) + +**Features:** +- Automatically adds appropriate CSS classes +- Injects SVG content for icons +- Works with any HTML element + +## CSS Variables + +The library uses CSS variables for theming. You can customize colors by defining these variables: + +```css +:root { + --ui-color-menu-bg: #343a40; /* Menu background */ + --ui-color-menu-text: #ffffff; /* Menu text color */ + --ui-color-menu-hover: rgba(255, 255, 255, 0.1); /* Hover effect */ + --ui-color-menu-active: #2c2c2c; /* Active item background */ + --ui-color-icon-primary: #2c3e50; /* Icon color */ +} +``` + +## Complete Example ```typescript -import { CardComponent } from '@ngshack/ui'; +import { Component } from '@angular/core'; +import { LayoutModule } from '@workshack/ui'; @Component({ - imports: [CardComponent], + selector: 'app-root', + imports: [LayoutModule], template: ` - -

Card content goes here

- -
- -
- -
- -
-
- ` + + + + + + + + + + + + + + + + +
+ +

Welcome to Dashboard

+

This is the main content area.

+
+
+
+ `, + styles: [` + .content-body { + padding: 1rem; + } + .btn { + margin-left: 0.5rem; + padding: 0.5rem 1rem; + border: none; + border-radius: 4px; + cursor: pointer; + } + .btn-primary { + background: #007bff; + color: white; + } + .btn-secondary { + background: #6c757d; + color: white; + } + `] }) -export class MyComponent {} +export class AppComponent { + navigate(route: string) { + console.log('Navigate to:', route); + } + + addNew() { + console.log('Add new item'); + } + + export() { + console.log('Export data'); + } +} ``` -#### Properties -- `title`: string (optional) -- `elevated`: boolean (default: false) -- `compact`: boolean (default: false) - ## Development ### Building - ```bash npm run build:ui ``` ### Watching for changes - ```bash npm run watch:ui ``` -### Publishing +### Testing +```bash +npm run test:ui +``` +### Publishing ```bash npm run publish:ui ``` -## Styling - -The library uses a gaming console theme with: -- Dark backgrounds with transparency -- Neon green accents (#00ff88) -- Smooth transitions and hover effects -- Backdrop blur effects - ## License -MIT +This library is licensed under a custom license that allows: -## Running unit tests +- **Free use** for non-commercial applications (no revenue, no ads, no paid features) +- **Commercial use** with attribution requirement - you must credit the library in your app (e.g., on an "About" or "For Developers" page) -To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command: +For full license terms, see the [LICENSE](LICENSE) file. + +### Attribution Example for Commercial Use -```bash -ng test ``` - -## Running end-to-end tests - -For end-to-end (e2e) testing, run: - -```bash -ng e2e +This application uses Workshack UI Library +(https://www.npmjs.com/package/@workshack/ui) +© 2025 Workshack Team ``` - -Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. - -## Additional Resources - -For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. diff --git a/package.json b/package.json index 083c4a3..83b7fd2 100644 --- a/package.json +++ b/package.json @@ -1,36 +1,25 @@ { - "name": "@ngshack/ui", - "version": "0.0.1", - "description": "Webland UI component library", - "author": "Webland Team", - "license": "MIT", - "keywords": ["angular", "ui", "components", "webland"], + "name": "@workshack/ui", + "version": "1.0.0", + "description": "Workshack UI component library for Angular applications", + "author": "Workshack Team", + "license": "SEE LICENSE IN LICENSE", + "keywords": ["angular", "ui", "components", "workshack", "theme"], "repository": { "type": "git", - "url": "https://github.com/webland/webland.git", - "directory": "app/packages/ui" + "url": "https://git.fufle.net/Tools/UI.git", + "directory": "." }, - "homepage": "https://github.com/webland/webland#readme", + "homepage": "https://git.fufle.net/Tools/UI", "bugs": { - "url": "https://github.com/webland/webland/issues" + "url": "https://git.fufle.net/Tools/UI/issues" }, - "main": "bundles/webland-ui.umd.js", - "module": "fesm2022/webland-ui.mjs", + "main": "bundles/workshack-ui.umd.js", + "module": "fesm2022/workshack-ui.mjs", "typings": "index.d.ts", - "exports": { - "./package.json": { - "default": "./package.json" - }, - ".": { - "types": "./index.d.ts", - "esm2022": "./esm2022/webland-ui.mjs", - "esm": "./esm2022/webland-ui.mjs", - "default": "./fesm2022/webland-ui.mjs" - } - }, "peerDependencies": { - "@angular/common": "^20.1.0", - "@angular/core": "^20.1.0" + "@angular/common": "^20.1.3", + "@angular/core": "^20.1.3" }, "dependencies": { "tslib": "^2.3.0" diff --git a/src/lib/components/button/button.component.html b/src/lib/components/button/button.component.html new file mode 100644 index 0000000..40b3726 --- /dev/null +++ b/src/lib/components/button/button.component.html @@ -0,0 +1 @@ + diff --git a/src/lib/components/button/button.component.scss b/src/lib/components/button/button.component.scss new file mode 100644 index 0000000..6e3e28a --- /dev/null +++ b/src/lib/components/button/button.component.scss @@ -0,0 +1,12 @@ +:host{ + display: inline-flex; + cursor: pointer; + align-items: center; + justify-content: center; + padding: 0px 0.75rem; + &.focus, + &:active, + &:hover{ + background: var(--ui-color-button-hover, rgba(255, 255, 255, 0.1)); + } +} diff --git a/src/lib/components/button/button.component.ts b/src/lib/components/button/button.component.ts new file mode 100644 index 0000000..8961bfb --- /dev/null +++ b/src/lib/components/button/button.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ui-button', + imports: [], + templateUrl: './button.component.html', + styleUrl: './button.component.scss' +}) +export class ButtonComponent { + +} diff --git a/src/lib/components/card/card.component.html b/src/lib/components/card/card.component.html new file mode 100644 index 0000000..f2fda25 --- /dev/null +++ b/src/lib/components/card/card.component.html @@ -0,0 +1 @@ +

card works!

diff --git a/src/lib/components/card/card.component.scss b/src/lib/components/card/card.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/components/card/card.component.spec.ts b/src/lib/components/card/card.component.spec.ts new file mode 100644 index 0000000..7fc8912 --- /dev/null +++ b/src/lib/components/card/card.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CardComponent } from './card.component'; + +describe('CardComponent', () => { + let component: CardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [CardComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/lib/components/card/card.component.ts b/src/lib/components/card/card.component.ts new file mode 100644 index 0000000..2d4f2e6 --- /dev/null +++ b/src/lib/components/card/card.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ui-card', + imports: [], + templateUrl: './card.component.html', + styleUrl: './card.component.scss' +}) +export class CardComponent { + +} diff --git a/src/lib/modules/form/components/input/input.component.html b/src/lib/modules/form/components/input/input.component.html new file mode 100644 index 0000000..53c650d --- /dev/null +++ b/src/lib/modules/form/components/input/input.component.html @@ -0,0 +1 @@ +

input works!

diff --git a/src/lib/modules/form/components/input/input.component.scss b/src/lib/modules/form/components/input/input.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/modules/form/components/input/input.component.spec.ts b/src/lib/modules/form/components/input/input.component.spec.ts new file mode 100644 index 0000000..9f17839 --- /dev/null +++ b/src/lib/modules/form/components/input/input.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { InputComponent } from './input.component'; + +describe('InputComponent', () => { + let component: InputComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [InputComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(InputComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/lib/modules/form/components/input/input.component.ts b/src/lib/modules/form/components/input/input.component.ts new file mode 100644 index 0000000..18ed28a --- /dev/null +++ b/src/lib/modules/form/components/input/input.component.ts @@ -0,0 +1,11 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ui-input', + imports: [], + templateUrl: './input.component.html', + styleUrl: './input.component.scss' +}) +export class InputComponent { + +} diff --git a/src/lib/modules/form/form-module.ts b/src/lib/modules/form/form-module.ts new file mode 100644 index 0000000..b8a8ef6 --- /dev/null +++ b/src/lib/modules/form/form-module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + + + +@NgModule({ + declarations: [], + imports: [ + CommonModule + ] +}) +export class FormModule { } diff --git a/src/lib/modules/layout/components/content/content.component.scss b/src/lib/modules/layout/components/content/content.component.scss index 22fc13a..a3b496d 100644 --- a/src/lib/modules/layout/components/content/content.component.scss +++ b/src/lib/modules/layout/components/content/content.component.scss @@ -2,6 +2,8 @@ display: block; flex-grow: 1; overflow: auto; - background: #333; - color: #fff; + + /* Theme-aware styles using CSS variables */ + background: var(--ui-color-content-bg, #363636); + color: var(--ui-color-content-text, #ffffff); } diff --git a/src/lib/modules/layout/components/header/header.component.html b/src/lib/modules/layout/components/header/header.component.html new file mode 100644 index 0000000..ec14437 --- /dev/null +++ b/src/lib/modules/layout/components/header/header.component.html @@ -0,0 +1,3 @@ + +
{{ label() }}
+ diff --git a/src/lib/modules/layout/components/header/header.component.scss b/src/lib/modules/layout/components/header/header.component.scss new file mode 100644 index 0000000..415477f --- /dev/null +++ b/src/lib/modules/layout/components/header/header.component.scss @@ -0,0 +1,18 @@ +:host{ + display: flex; + width: 100%; + align-items: stretch; + min-height: 4rem; + background: var(--ui-color-menu-bg, #343a40); + color: var(--ui-color-menu-text, #ffffff); + .title{ + display: flex; + align-items: center; + flex-grow: 1; + font-size: 1.618rem; + padding-left: 0.5rem; + } + ::ng-deep ui-button{ + min-width: 4rem; + } +} diff --git a/src/lib/modules/layout/components/header/header.component.spec.ts b/src/lib/modules/layout/components/header/header.component.spec.ts new file mode 100644 index 0000000..204ed6e --- /dev/null +++ b/src/lib/modules/layout/components/header/header.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HeaderComponent } from './header.component'; + +describe('HeaderComponent', () => { + let component: HeaderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [HeaderComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(HeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/lib/modules/layout/components/header/header.component.ts b/src/lib/modules/layout/components/header/header.component.ts new file mode 100644 index 0000000..d7c90cb --- /dev/null +++ b/src/lib/modules/layout/components/header/header.component.ts @@ -0,0 +1,13 @@ +import { Component, input, output } from '@angular/core'; + +@Component({ + selector: 'ui-header', + imports: [], + templateUrl: './header.component.html', + styleUrl: './header.component.scss' +}) +export class HeaderComponent { + label = input(''); + back = input(false); + onback = output(); +} diff --git a/src/lib/modules/layout/components/menu-item/menu-item.component.scss b/src/lib/modules/layout/components/menu-item/menu-item.component.scss index 3496b32..983fe74 100644 --- a/src/lib/modules/layout/components/menu-item/menu-item.component.scss +++ b/src/lib/modules/layout/components/menu-item/menu-item.component.scss @@ -5,19 +5,25 @@ flex-direction: column; justify-content: center; align-items: center; + cursor: pointer; + background: var(--ui-color-menu-bg, #343a40); + color: var(--ui-color-menu-text, #ffffff); + + &.active { + background: var(--ui-color-menu-active, #2c2c2c); + } + + &.focus, + &:active, + &:hover { + background: var(--ui-color-menu-hover, rgba(255, 255, 255, 0.1)); + } i { font-size: 1.7rem; + color: var(--ui-color-icon-primary, #2c3e50); } span{ font-size: 0.6rem; } - &.active{ - background: #333; - } - &.focus, - &:active, - &:hover{ - background: #222; - } } diff --git a/src/lib/modules/layout/components/menu/menu.component.scss b/src/lib/modules/layout/components/menu/menu.component.scss index 4601199..0838791 100644 --- a/src/lib/modules/layout/components/menu/menu.component.scss +++ b/src/lib/modules/layout/components/menu/menu.component.scss @@ -1,7 +1,7 @@ :host{ width: 4rem; - background: #444; - color: #fff; display: flex; flex-direction: column; + background: var(--ui-color-menu-bg, #343a40); + color: var(--ui-color-menu-text, #ffffff); } diff --git a/src/lib/modules/layout/layout-module.ts b/src/lib/modules/layout/layout-module.ts index 1d30209..d08435c 100644 --- a/src/lib/modules/layout/layout-module.ts +++ b/src/lib/modules/layout/layout-module.ts @@ -4,6 +4,7 @@ import { LayoutComponent } from "./components/layout/layout.component"; import { MenuComponent } from "./components/menu/menu.component"; import { MenuItemComponent } from "./components/menu-item/menu-item.component"; import { ContentComponent } from "./components/content/content.component"; +import { HeaderComponent } from "./components/header/header.component"; @NgModule({ declarations: [], @@ -13,12 +14,14 @@ import { ContentComponent } from "./components/content/content.component"; MenuComponent, MenuItemComponent, ContentComponent, + HeaderComponent, ], exports: [ LayoutComponent, MenuComponent, MenuItemComponent, ContentComponent, + HeaderComponent, ] }) export class LayoutModule { } diff --git a/src/lib/styles/_theme-mixins.scss b/src/lib/styles/_theme-mixins.scss new file mode 100644 index 0000000..ff7ce50 --- /dev/null +++ b/src/lib/styles/_theme-mixins.scss @@ -0,0 +1,86 @@ +/* Theme Integration Mixins for UI Library */ + +/** + * Mixin that generates CSS variables for UI library components + * This mixin should be called by the main application to provide colors for the UI library + * The UI library uses only --ui-* variables with hardcoded fallbacks for portability + * + * @param $primary - Primary color for the theme + * @param $secondary - Secondary color for the theme + * @param $background - Background color for the theme + * @param $text - Text color for the theme + * @param $border - Border color for the theme + * @param $hover - Hover state color for the theme + */ +@mixin ui-theme-variables( + $primary: #2c3e50, + $secondary: #666666, + $background: #343a40, + $text: #ffffff, + $border: #d0d0d0, + $hover: rgba(255, 255, 255, 0.1) +) { + /* UI Library specific CSS variables - only these should be used in UI components */ + --ui-color-primary: #{$primary}; + --ui-color-secondary: #{$secondary}; + --ui-color-background: #{$background}; + --ui-color-text: #{$text}; + --ui-color-border: #{$border}; + --ui-color-hover: #{$hover}; + + /* Derived colors for specific UI components */ + --ui-color-menu-bg: #{$background}; + --ui-color-menu-text: #{$text}; + --ui-color-menu-hover: #{$hover}; + --ui-color-menu-active: color-mix(in srgb, #{$background} 80%, black 20%); + --ui-color-menu-border: #{$border}; + + --ui-color-content-bg: color-mix(in srgb, #{$background} 95%, white 5%); + --ui-color-content-text: #{$text}; + + --ui-color-icon-primary: #{$primary}; + --ui-color-icon-secondary: #{$secondary}; + --ui-color-icon-muted: color-mix(in srgb, #{$text} 60%, transparent 40%); +} + +/** + * Mixin that applies theme-aware styles to menu components + */ +@mixin ui-menu-theme() { + background: var(--ui-color-menu-bg); + color: var(--ui-color-menu-text); + border-right: 1px solid var(--ui-color-menu-border); + + &.active { + background: var(--ui-color-menu-active); + } + + &.focus, + &:active, + &:hover { + background: var(--ui-color-menu-hover); + } +} + +/** + * Mixin that applies theme-aware styles to content components + */ +@mixin ui-content-theme() { + background: var(--ui-color-content-bg); + color: var(--ui-color-content-text); +} + +/** + * Mixin that applies theme-aware styles to icon components + */ +@mixin ui-icon-theme($variant: 'primary') { + @if $variant == 'primary' { + color: var(--ui-color-icon-primary); + } @else if $variant == 'secondary' { + color: var(--ui-color-icon-secondary); + } @else if $variant == 'muted' { + color: var(--ui-color-icon-muted); + } +} + + diff --git a/src/lib/styles/integration-example.scss b/src/lib/styles/integration-example.scss new file mode 100644 index 0000000..21b220c --- /dev/null +++ b/src/lib/styles/integration-example.scss @@ -0,0 +1,43 @@ +/* + * Integration Example for Main Application + * + * To integrate the UI library with your main application's theme system: + * + * 1. Import this file in your main styles.scss AFTER importing themes.scss: + * @use 'packages/ui/src/lib/styles/ui-themes'; + * + * 2. Or manually include the theme generation in your themes.scss: + * @use 'packages/ui/src/lib/styles/theme-mixins' as ui-theme; + * @include ui-theme.ui-generate-theme-variants(); + * + * 3. The UI library components will automatically adapt to your theme changes + * + * Example usage in main application styles.scss: + */ + +/* +@use 'themes'; +@use 'packages/ui/src/lib/styles/ui-themes'; + +// Your existing styles... +*/ + +/* + * Custom theme integration example: + * If you want to customize UI library colors differently from main app: + */ + +/* +@use 'packages/ui/src/lib/styles/theme-mixins' as ui-theme; + +html[theme="custom-theme"] { + @include ui-theme.ui-theme-variables( + $primary: #your-primary-color, + $secondary: #your-secondary-color, + $background: #your-background-color, + $text: #your-text-color, + $border: #your-border-color, + $hover: rgba(255, 255, 255, 0.1) + ); +} +*/ diff --git a/src/lib/styles/ui-themes.scss b/src/lib/styles/ui-themes.scss new file mode 100644 index 0000000..e280531 --- /dev/null +++ b/src/lib/styles/ui-themes.scss @@ -0,0 +1,4 @@ +/* Main UI Library Theme Integration */ + +/* Export mixins for use by main application */ +@forward 'theme-mixins'; diff --git a/src/public-api.ts b/src/public-api.ts index d2ae6c3..0d7c441 100644 --- a/src/public-api.ts +++ b/src/public-api.ts @@ -4,11 +4,16 @@ // Layout Module export * from './lib/modules/layout/layout-module'; - -// Layout Components export * from './lib/modules/layout/components/layout/layout.component'; export * from './lib/modules/layout/components/menu/menu.component'; export * from './lib/modules/layout/components/menu-item/menu-item.component'; export * from './lib/modules/layout/components/content/content.component'; +export * from './lib/modules/layout/components/header/header.component'; +// Form Module +export * from './lib/modules/form/form-module'; +export * from './lib/modules/form/components/input/input.component'; +// Components +export * from './lib/components/button/button.component'; +export * from './lib/components/card/card.component';