add components

This commit is contained in:
Michał Sieciechowicz 2025-08-02 18:55:34 +02:00
parent 6a8d0370e1
commit 678ce12de4
30 changed files with 804 additions and 143 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
cache

31
.npmignore Normal file
View File

@ -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*

55
LICENSE Normal file
View File

@ -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.

124
README-THEME-INTEGRATION.md Normal file
View File

@ -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

357
README.md
View File

@ -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: `
<wl-ui-button variant="primary">Click me</wl-ui-button>
<wl-ui-button variant="secondary" size="lg">Large Button</wl-ui-button>
<wl-ui-button variant="outline" [disabled]="true">Disabled</wl-ui-button>
<ui-layout>
<ui-menu>
<ui-menu-item label="Home" icon="home"></ui-menu-item>
<ui-menu-item label="Settings" icon="settings"></ui-menu-item>
</ui-menu>
<ui-content>
<ui-header label="Page Title">
<button>Action Button</button>
</ui-header>
<!-- Your content here -->
</ui-content>
</ui-layout>
`
})
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 (`<ui-layout>`)
**Selector:** `ui-layout`
**Description:** Root container component that provides the main layout structure.
**Usage:**
```html
<ui-layout>
<!-- Menu and content components go here -->
</ui-layout>
```
**Properties:** None
**Content Projection:** Accepts any content, typically `ui-menu` and `ui-content`
---
#### MenuComponent (`<ui-menu>`)
**Selector:** `ui-menu`
**Description:** Vertical sidebar menu container for navigation items.
**Usage:**
```html
<ui-menu>
<ui-menu-item label="Dashboard" icon="dashboard"></ui-menu-item>
<ui-menu-item label="Users" icon="people"></ui-menu-item>
</ui-menu>
```
**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 (`<ui-menu-item>`)
**Selector:** `ui-menu-item`
**Description:** Individual menu item with icon and label.
**Usage:**
```html
<ui-menu-item
label="Dashboard"
icon="dashboard">
</ui-menu-item>
```
**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 (`<ui-content>`)
**Selector:** `ui-content`
**Description:** Main content area container.
**Usage:**
```html
<ui-content>
<ui-header label="Page Title"></ui-header>
<!-- Your page content -->
</ui-content>
```
**Properties:** None
**Content Projection:** Accepts any content, typically starts with `ui-header`
---
#### HeaderComponent (`<ui-header>`)
**Selector:** `ui-header`
**Description:** Page header with title and action buttons.
**Usage:**
```html
<ui-header label="Dashboard">
<button class="btn btn-primary">Add New</button>
<button class="btn btn-secondary">Export</button>
</ui-header>
```
**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
<i uiIcon="home"></i>
<span uiIcon="settings"></span>
```
**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: `
<wl-ui-card title="My Card" [elevated]="true">
<p>Card content goes here</p>
<div slot="header">
<button>Header Action</button>
</div>
<div slot="footer">
<button>Footer Action</button>
</div>
</wl-ui-card>
`
<ui-layout>
<ui-menu>
<ui-menu-item
label="Dashboard"
icon="dashboard"
(click)="navigate('dashboard')">
</ui-menu-item>
<ui-menu-item
label="Users"
icon="user"
(click)="navigate('users')">
</ui-menu-item>
<ui-menu-item
label="Settings"
icon="settings"
(click)="navigate('settings')">
</ui-menu-item>
</ui-menu>
<ui-content>
<ui-header label="Dashboard">
<button class="btn btn-primary" (click)="addNew()">
<i uiIcon="add"></i> Add New
</button>
<button class="btn btn-secondary" (click)="export()">
<i uiIcon="download"></i> Export
</button>
</ui-header>
<div class="content-body">
<!-- Your page content here -->
<h2>Welcome to Dashboard</h2>
<p>This is the main content area.</p>
</div>
</ui-content>
</ui-layout>
`,
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.

View File

@ -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"

View File

@ -0,0 +1 @@
<ng-content />

View File

@ -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));
}
}

View File

@ -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 {
}

View File

@ -0,0 +1 @@
<p>card works!</p>

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CardComponent } from './card.component';
describe('CardComponent', () => {
let component: CardComponent;
let fixture: ComponentFixture<CardComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [CardComponent]
})
.compileComponents();
fixture = TestBed.createComponent(CardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -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 {
}

View File

@ -0,0 +1 @@
<p>input works!</p>

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { InputComponent } from './input.component';
describe('InputComponent', () => {
let component: InputComponent;
let fixture: ComponentFixture<InputComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [InputComponent]
})
.compileComponents();
fixture = TestBed.createComponent(InputComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -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 {
}

View File

@ -0,0 +1,12 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
declarations: [],
imports: [
CommonModule
]
})
export class FormModule { }

View File

@ -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);
}

View File

@ -0,0 +1,3 @@
<ng-content select="[side=left]"></ng-content>
<div class="title">{{ label() }}</div>
<ng-content />

View File

@ -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;
}
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HeaderComponent } from './header.component';
describe('HeaderComponent', () => {
let component: HeaderComponent;
let fixture: ComponentFixture<HeaderComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HeaderComponent]
})
.compileComponents();
fixture = TestBed.createComponent(HeaderComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -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<string>('');
back = input<boolean>(false);
onback = output<void>();
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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 { }

View File

@ -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);
}
}

View File

@ -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)
);
}
*/

View File

@ -0,0 +1,4 @@
/* Main UI Library Theme Integration */
/* Export mixins for use by main application */
@forward 'theme-mixins';

View File

@ -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';