Add comprehensive library expansion with new components and demos
- Add new libraries: ui-accessibility, ui-animations, ui-backgrounds, ui-code-display, ui-data-utils, ui-font-manager, hcl-studio - Add extensive layout components: gallery-grid, infinite-scroll-container, kanban-board, masonry, split-view, sticky-layout - Add comprehensive demo components for all new features - Update project configuration and dependencies - Expand component exports and routing structure - Add UI landing pages planning document 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import { Component, Input, OnInit, OnDestroy, OnChanges, SimpleChanges, ElementRef, inject, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
|
||||
import { LinearGradientConfig, RadialGradientConfig, ConicGradientConfig, ColorStop, GradientDirection } from '../../types/background.types';
|
||||
import { BackgroundService } from '../../services/background.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-gradient-background',
|
||||
standalone: true,
|
||||
template: '<ng-content></ng-content>',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: {
|
||||
'class': 'ui-background ui-background--gradient'
|
||||
}
|
||||
})
|
||||
export class GradientBackgroundComponent implements OnInit, OnDestroy, OnChanges {
|
||||
private readonly elementRef = inject(ElementRef<HTMLElement>);
|
||||
private readonly backgroundService = inject(BackgroundService);
|
||||
private backgroundId?: string;
|
||||
|
||||
@Input() type: 'linear' | 'radial' | 'conic' = 'linear';
|
||||
@Input() colors: string[] = ['#000000', '#ffffff'];
|
||||
@Input() direction?: GradientDirection | string;
|
||||
@Input() shape?: 'circle' | 'ellipse';
|
||||
@Input() size?: 'closest-side' | 'closest-corner' | 'farthest-side' | 'farthest-corner';
|
||||
@Input() position?: string;
|
||||
@Input() angle?: string | number;
|
||||
@Input() colorStops?: ColorStop[];
|
||||
@Input() fullScreen = false;
|
||||
@Input() zIndex?: number;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.applyBackground();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
const relevantChanges = ['type', 'colors', 'direction', 'shape', 'size', 'position', 'angle', 'colorStops', 'fullScreen', 'zIndex'];
|
||||
if (relevantChanges.some(key => changes[key])) {
|
||||
this.applyBackground();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.backgroundId) {
|
||||
this.backgroundService.removeBackground(this.backgroundId);
|
||||
}
|
||||
}
|
||||
|
||||
private applyBackground(): void {
|
||||
if (this.backgroundId) {
|
||||
this.backgroundService.removeBackground(this.backgroundId);
|
||||
}
|
||||
|
||||
const colorStops = this.colorStops || this.colors.map(color => ({ color }));
|
||||
let config: LinearGradientConfig | RadialGradientConfig | ConicGradientConfig;
|
||||
|
||||
switch (this.type) {
|
||||
case 'linear':
|
||||
config = {
|
||||
type: 'linear-gradient',
|
||||
direction: this.direction,
|
||||
colors: colorStops
|
||||
};
|
||||
break;
|
||||
case 'radial':
|
||||
config = {
|
||||
type: 'radial-gradient',
|
||||
shape: this.shape,
|
||||
size: this.size,
|
||||
position: this.position,
|
||||
colors: colorStops
|
||||
};
|
||||
break;
|
||||
case 'conic':
|
||||
config = {
|
||||
type: 'conic-gradient',
|
||||
angle: this.angle,
|
||||
position: this.position,
|
||||
colors: colorStops
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.fullScreen) {
|
||||
this.backgroundId = this.backgroundService.applyFullScreenBackground(config, {
|
||||
zIndex: this.zIndex || -1
|
||||
});
|
||||
} else {
|
||||
this.backgroundId = this.backgroundService.applyBackground(
|
||||
this.elementRef.nativeElement,
|
||||
config
|
||||
);
|
||||
}
|
||||
|
||||
// Update host class
|
||||
this.elementRef.nativeElement.classList.add(`ui-background--${this.type}-gradient`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import { Component, Input, OnInit, OnDestroy, OnChanges, SimpleChanges, ElementRef, inject, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
|
||||
import { ImageBackgroundConfig } from '../../types/background.types';
|
||||
import { BackgroundService } from '../../services/background.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-image-background',
|
||||
standalone: true,
|
||||
template: '<ng-content></ng-content>',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: {
|
||||
'class': 'ui-background ui-background--image'
|
||||
}
|
||||
})
|
||||
export class ImageBackgroundComponent implements OnInit, OnDestroy, OnChanges {
|
||||
private readonly elementRef = inject(ElementRef<HTMLElement>);
|
||||
private readonly backgroundService = inject(BackgroundService);
|
||||
private backgroundId?: string;
|
||||
|
||||
@Input({ required: true }) url!: string;
|
||||
@Input() size: 'auto' | 'cover' | 'contain' | string = 'cover';
|
||||
@Input() position = 'center';
|
||||
@Input() repeat: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat' = 'no-repeat';
|
||||
@Input() attachment?: 'scroll' | 'fixed' | 'local';
|
||||
@Input() opacity = 1;
|
||||
@Input() fullScreen = false;
|
||||
@Input() zIndex?: number;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.applyBackground();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
const relevantChanges = ['url', 'size', 'position', 'repeat', 'attachment', 'opacity', 'fullScreen', 'zIndex'];
|
||||
if (relevantChanges.some(key => changes[key])) {
|
||||
this.applyBackground();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.backgroundId) {
|
||||
this.backgroundService.removeBackground(this.backgroundId);
|
||||
}
|
||||
}
|
||||
|
||||
private applyBackground(): void {
|
||||
if (!this.url) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.backgroundId) {
|
||||
this.backgroundService.removeBackground(this.backgroundId);
|
||||
}
|
||||
|
||||
const config: ImageBackgroundConfig = {
|
||||
type: 'image',
|
||||
url: this.url,
|
||||
size: this.size,
|
||||
position: this.position,
|
||||
repeat: this.repeat,
|
||||
attachment: this.attachment,
|
||||
opacity: this.opacity
|
||||
};
|
||||
|
||||
if (this.fullScreen) {
|
||||
this.backgroundId = this.backgroundService.applyFullScreenBackground(config, {
|
||||
zIndex: this.zIndex || -1
|
||||
});
|
||||
} else {
|
||||
this.backgroundId = this.backgroundService.applyBackground(
|
||||
this.elementRef.nativeElement,
|
||||
config
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from './solid-background.component';
|
||||
export * from './gradient-background.component';
|
||||
export * from './pattern-background.component';
|
||||
export * from './image-background.component';
|
||||
@@ -0,0 +1,73 @@
|
||||
import { Component, Input, OnInit, OnDestroy, OnChanges, SimpleChanges, ElementRef, inject, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
|
||||
import { PatternConfig, PatternType } from '../../types/background.types';
|
||||
import { BackgroundService } from '../../services/background.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-pattern-background',
|
||||
standalone: true,
|
||||
template: '<ng-content></ng-content>',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: {
|
||||
'class': 'ui-background ui-background--pattern'
|
||||
}
|
||||
})
|
||||
export class PatternBackgroundComponent implements OnInit, OnDestroy, OnChanges {
|
||||
private readonly elementRef = inject(ElementRef<HTMLElement>);
|
||||
private readonly backgroundService = inject(BackgroundService);
|
||||
private backgroundId?: string;
|
||||
|
||||
@Input() pattern: PatternType = 'dots';
|
||||
@Input() primaryColor = '#000000';
|
||||
@Input() secondaryColor = '#ffffff';
|
||||
@Input() size: string | number = 20;
|
||||
@Input() opacity = 1;
|
||||
@Input() fullScreen = false;
|
||||
@Input() zIndex?: number;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.applyBackground();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
const relevantChanges = ['pattern', 'primaryColor', 'secondaryColor', 'size', 'opacity', 'fullScreen', 'zIndex'];
|
||||
if (relevantChanges.some(key => changes[key])) {
|
||||
this.applyBackground();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.backgroundId) {
|
||||
this.backgroundService.removeBackground(this.backgroundId);
|
||||
}
|
||||
}
|
||||
|
||||
private applyBackground(): void {
|
||||
if (this.backgroundId) {
|
||||
this.backgroundService.removeBackground(this.backgroundId);
|
||||
}
|
||||
|
||||
const config: PatternConfig = {
|
||||
type: 'pattern',
|
||||
pattern: this.pattern,
|
||||
primaryColor: this.primaryColor,
|
||||
secondaryColor: this.secondaryColor,
|
||||
size: this.size,
|
||||
opacity: this.opacity
|
||||
};
|
||||
|
||||
if (this.fullScreen) {
|
||||
this.backgroundId = this.backgroundService.applyFullScreenBackground(config, {
|
||||
zIndex: this.zIndex || -1
|
||||
});
|
||||
} else {
|
||||
this.backgroundId = this.backgroundService.applyBackground(
|
||||
this.elementRef.nativeElement,
|
||||
config
|
||||
);
|
||||
}
|
||||
|
||||
// Update host class
|
||||
this.elementRef.nativeElement.classList.add(`ui-background--pattern-${this.pattern}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import { Component, Input, OnInit, OnDestroy, OnChanges, SimpleChanges, ElementRef, inject, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
|
||||
import { SolidBackgroundConfig } from '../../types/background.types';
|
||||
import { BackgroundService } from '../../services/background.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-solid-background',
|
||||
standalone: true,
|
||||
template: '<ng-content></ng-content>',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: {
|
||||
'class': 'ui-background ui-background--solid'
|
||||
}
|
||||
})
|
||||
export class SolidBackgroundComponent implements OnInit, OnDestroy, OnChanges {
|
||||
private readonly elementRef = inject(ElementRef<HTMLElement>);
|
||||
private readonly backgroundService = inject(BackgroundService);
|
||||
private backgroundId?: string;
|
||||
|
||||
@Input() color = '#000000';
|
||||
@Input() fullScreen = false;
|
||||
@Input() zIndex?: number;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.applyBackground();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes['color'] || changes['fullScreen'] || changes['zIndex']) {
|
||||
this.applyBackground();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.backgroundId) {
|
||||
this.backgroundService.removeBackground(this.backgroundId);
|
||||
}
|
||||
}
|
||||
|
||||
private applyBackground(): void {
|
||||
if (this.backgroundId) {
|
||||
this.backgroundService.removeBackground(this.backgroundId);
|
||||
}
|
||||
|
||||
const config: SolidBackgroundConfig = {
|
||||
type: 'solid',
|
||||
color: this.color
|
||||
};
|
||||
|
||||
if (this.fullScreen) {
|
||||
this.backgroundId = this.backgroundService.applyFullScreenBackground(config, {
|
||||
zIndex: this.zIndex || -1
|
||||
});
|
||||
} else {
|
||||
this.backgroundId = this.backgroundService.applyBackground(
|
||||
this.elementRef.nativeElement,
|
||||
config
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
1
projects/ui-backgrounds/src/lib/components/index.ts
Normal file
1
projects/ui-backgrounds/src/lib/components/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './backgrounds/index';
|
||||
Reference in New Issue
Block a user