@pegasusheavy/ngx-tailwindcss 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +19 -0
- package/CHANGELOG.md +163 -0
- package/LICENSE +22 -0
- package/README.md +342 -0
- package/commitlint.config.cjs +4 -0
- package/package.json +144 -0
package/.prettierignore
ADDED
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2025-12-19
|
|
9
|
+
|
|
10
|
+
### ✨ Features
|
|
11
|
+
|
|
12
|
+
- Introduced a configurable theming system based on CSS custom properties, the `TwThemeService`, and `provideTwTheme()` so apps can swap palettes, override individual components, and keep `dark:` styles optional.
|
|
13
|
+
- Added a default `theme.css` bundle with semantic light/dark values and exposed the CSS variables through `ng-packagr` assets, letting downstream consumers tweak every shade without touching the library source.
|
|
14
|
+
- Delivered `TwDatatablesComponent`, a ready-to-go dashboard table with headers, toolbar slots, filters, pagination, and selection wired to the existing `tw-table` data layer.
|
|
15
|
+
|
|
16
|
+
### 📝 Content & polish
|
|
17
|
+
|
|
18
|
+
- Documented how to configure themes and added the DataTables docs page, ensuring the sidebar, nav, and theming routes all reach the new experiences.
|
|
19
|
+
- Rebalanced the docs palette so dark mode text, containers, stack/grid/spacer demos, sticky/scroll-area/columns/bleed examples, and tabs are legible, spacing works, and the navbar no longer looks cramped.
|
|
20
|
+
- Fixed the horizontal spacer sample to honor `size="auto"` by giving it `flex-1` and updated copy snippets throughout the docs to reflect the new UX.
|
|
21
|
+
|
|
22
|
+
### 🛠 Tooling & quality
|
|
23
|
+
|
|
24
|
+
- Added comprehensive `.npmignore`, removed single-use scripts, and wired Husky with linting pre-commit, test pre-push, and commitlint hooks.
|
|
25
|
+
- Documented the new changelog entry, ensured dark-mode demos showcase `dark:text-slate-300`, and kept existing Tailwind `dark:` utilities as safe defaults while giving users CSS variable overrides for Tw components.
|
|
26
|
+
|
|
27
|
+
## [0.1.0-beta.1] - 2025-12-15
|
|
28
|
+
|
|
29
|
+
### 🎉 Initial Release
|
|
30
|
+
|
|
31
|
+
First public release of `@pegasus-heavy/ngx-tailwindcss` - A highly customizable Angular component library for Tailwind CSS 4+.
|
|
32
|
+
|
|
33
|
+
### ✨ Features
|
|
34
|
+
|
|
35
|
+
#### Core
|
|
36
|
+
- **TwClassService** - Intelligent Tailwind class merging with conflict resolution
|
|
37
|
+
- **Global Configuration** - `provideTwConfig()` for app-wide default styling
|
|
38
|
+
- **Class Override System** - `classOverride` and `classReplace` inputs on all components
|
|
39
|
+
|
|
40
|
+
#### Form Components
|
|
41
|
+
- **Button** - Multiple variants (primary, secondary, outline, ghost, link, danger), sizes, icons, loading states
|
|
42
|
+
- **Input** - Text, password, email, number inputs with validation, prefixes, suffixes
|
|
43
|
+
- **Checkbox** - Single and group checkboxes with indeterminate state
|
|
44
|
+
- **Radio** - Radio buttons with group support
|
|
45
|
+
- **Switch** - Toggle switches with labels
|
|
46
|
+
- **Select** - Dropdown select with search, multi-select, custom templates
|
|
47
|
+
- **Slider** - Range sliders with single/dual handles, steps, marks
|
|
48
|
+
- **Rating** - Star rating with half-star support
|
|
49
|
+
|
|
50
|
+
#### Layout Components
|
|
51
|
+
- **Card** - Flexible card layouts with header, body, footer directives
|
|
52
|
+
- **Accordion** - Collapsible panels with single/multiple open modes
|
|
53
|
+
- **Tabs** - Tab navigation with lazy loading support
|
|
54
|
+
- **Divider** - Horizontal/vertical dividers with labels
|
|
55
|
+
|
|
56
|
+
#### Data Display Components
|
|
57
|
+
- **Badge** - Status indicators with variants and sizes
|
|
58
|
+
- **Avatar** - User avatars with images, initials, status indicators, groups
|
|
59
|
+
- **Chip** - Removable chips/tags
|
|
60
|
+
- **Table** - Data tables with sorting, pagination, row selection
|
|
61
|
+
- **Tree** - Hierarchical tree view with expand/collapse
|
|
62
|
+
- **Timeline** - Vertical timeline for events
|
|
63
|
+
|
|
64
|
+
#### Navigation Components
|
|
65
|
+
- **Breadcrumb** - Navigation breadcrumbs with custom separators
|
|
66
|
+
- **Pagination** - Page navigation with customizable display
|
|
67
|
+
- **Steps** - Step indicators for multi-step processes
|
|
68
|
+
- **Menu** - Context menus and menu bars
|
|
69
|
+
|
|
70
|
+
#### Feedback Components
|
|
71
|
+
- **Alert** - Dismissible alerts with variants (info, success, warning, error)
|
|
72
|
+
- **Toast** - Toast notifications with positioning and auto-dismiss
|
|
73
|
+
- **Progress** - Linear and circular progress bars
|
|
74
|
+
- **Spinner** - Loading spinners (border, dots, pulse, bars)
|
|
75
|
+
- **Skeleton** - Loading placeholders (text, cards, tables)
|
|
76
|
+
|
|
77
|
+
#### Overlay Components
|
|
78
|
+
- **Modal** - Dialog modals with sizes and animations
|
|
79
|
+
- **Dropdown** - Dropdown menus with portal rendering
|
|
80
|
+
- **Sidebar** - Slide-out sidebar panels
|
|
81
|
+
- **Popover** - Floating popovers with positioning
|
|
82
|
+
|
|
83
|
+
#### Media Components
|
|
84
|
+
- **Image** - Responsive images with lazy loading, preview mode
|
|
85
|
+
|
|
86
|
+
#### Utility Components
|
|
87
|
+
- **ScrollTop** - Scroll-to-top button
|
|
88
|
+
|
|
89
|
+
### 🎯 Directives
|
|
90
|
+
|
|
91
|
+
#### Core Directives
|
|
92
|
+
- **TwRippleDirective** - Material-style ripple effects
|
|
93
|
+
- **TwTooltipDirective** - Tooltip on hover
|
|
94
|
+
- **TwClickOutsideDirective** - Detect clicks outside element
|
|
95
|
+
- **TwFocusTrapDirective** - Trap focus within modals
|
|
96
|
+
|
|
97
|
+
#### DX Enhancement Directives
|
|
98
|
+
- **TwAutoFocusDirective** - Auto-focus elements on render
|
|
99
|
+
- **TwInViewDirective** - Intersection Observer for visibility
|
|
100
|
+
- **TwLongPressDirective** - Detect long press gestures
|
|
101
|
+
- **TwDebounceClickDirective** - Debounce rapid clicks
|
|
102
|
+
- **TwCopyClipboardDirective** - Copy text to clipboard
|
|
103
|
+
- **TwKeyboardShortcutDirective** - Handle keyboard shortcuts
|
|
104
|
+
- **TwSwipeDirective** - Detect swipe gestures
|
|
105
|
+
- **TwResizeObserverDirective** - Observe element resize
|
|
106
|
+
- **TwLazyImageDirective** - Lazy load images
|
|
107
|
+
- **TwScrollToDirective** - Smooth scroll navigation
|
|
108
|
+
- **TwHoverClassDirective** - Dynamic hover classes
|
|
109
|
+
- **TwTrapScrollDirective** - Prevent scroll propagation
|
|
110
|
+
|
|
111
|
+
#### ARIA Accessibility Directives
|
|
112
|
+
- **TwSrOnlyDirective** - Screen reader only content
|
|
113
|
+
- **TwAnnounceDirective** - Screen reader announcements
|
|
114
|
+
- **TwAriaExpandedDirective** - Manage expanded state
|
|
115
|
+
- **TwAriaSelectedDirective** - Manage selected state
|
|
116
|
+
- **TwAriaCheckedDirective** - Manage checked state
|
|
117
|
+
- **TwAriaPressedDirective** - Manage pressed state
|
|
118
|
+
- **TwAriaDisabledDirective** - Manage disabled state
|
|
119
|
+
- **TwAriaHiddenDirective** - Hide from assistive tech
|
|
120
|
+
- **TwAriaLiveDirective** - Live region management
|
|
121
|
+
- **TwAriaCurrentDirective** - Current navigation item
|
|
122
|
+
- **TwAriaBusyDirective** - Busy/loading state
|
|
123
|
+
- **TwAriaDescribedbyDirective** - Description relationships
|
|
124
|
+
- **TwAriaLabelledbyDirective** - Label relationships
|
|
125
|
+
- **TwAriaLabelDirective** - Accessible labels
|
|
126
|
+
- **TwAriaValueDirective** - Range widget values
|
|
127
|
+
- **TwRoleDirective** - ARIA roles
|
|
128
|
+
- **TwAriaModalDirective** - Modal dialogs
|
|
129
|
+
- **TwAriaHaspopupDirective** - Popup indicators
|
|
130
|
+
|
|
131
|
+
### ♿ Accessibility
|
|
132
|
+
- **TwAriaService** - Screen reader announcements (polite/assertive)
|
|
133
|
+
- **AriaUtils** - Helper functions for ARIA IDs and attributes
|
|
134
|
+
- All components built with WCAG 2.1 guidelines
|
|
135
|
+
- Keyboard navigation support
|
|
136
|
+
- Focus management
|
|
137
|
+
|
|
138
|
+
### 🌐 Internationalization
|
|
139
|
+
- **TwI18nService** - Translation and locale management
|
|
140
|
+
- **provideTwTranslations()** - Custom translation provider
|
|
141
|
+
- **provideTwLocale()** - Locale configuration
|
|
142
|
+
- Default English translations for all components
|
|
143
|
+
- RTL language support (Arabic, Hebrew, Persian, Urdu, etc.)
|
|
144
|
+
- String interpolation for dynamic content
|
|
145
|
+
|
|
146
|
+
### 📚 Documentation
|
|
147
|
+
- Comprehensive docs website with live examples
|
|
148
|
+
- Interactive component demos
|
|
149
|
+
- Code snippets with copy functionality
|
|
150
|
+
- SEO optimized with Open Graph and Twitter Cards
|
|
151
|
+
- AI-friendly documentation (llms.txt, structured data)
|
|
152
|
+
|
|
153
|
+
### 🛠️ Developer Experience
|
|
154
|
+
- Angular 19, 20, and 21 support
|
|
155
|
+
- Standalone components (no NgModule required)
|
|
156
|
+
- Full TypeScript support with strict types
|
|
157
|
+
- Tree-shakeable exports
|
|
158
|
+
- Zero bundled CSS - works with your Tailwind config
|
|
159
|
+
- Signals-based reactive state management
|
|
160
|
+
|
|
161
|
+
[0.1.0]: https://github.com/pegasusheavy/ngx-tailwindcss/releases/tag/v0.1.0
|
|
162
|
+
[0.1.0-beta.1]: https://github.com/pegasusheavy/ngx-tailwindcss/releases/tag/v0.1.0-beta.1
|
|
163
|
+
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Pegasus Heavy Industries LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# @pegasus-heavy/ngx-tailwindcss
|
|
2
|
+
|
|
3
|
+
A highly customizable Angular component library designed for **Tailwind CSS 4+**. This library provides beautiful, accessible UI components that leverage Tailwind's utility-first approach while giving you complete control over styling.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎨 **Fully Customizable** - Override any styling through class props or global configuration
|
|
8
|
+
- 🌊 **Tailwind CSS 4+ Ready** - Built for the latest Tailwind with CSS-first configuration
|
|
9
|
+
- ♿ **Accessible** - WCAG compliant with proper ARIA attributes and keyboard navigation
|
|
10
|
+
- 📦 **Tree-Shakeable** - Import only what you need with secondary entry points
|
|
11
|
+
- 🔧 **No Bundled CSS** - Your Tailwind config, your rules
|
|
12
|
+
- ⚡ **Standalone Components** - No NgModule required, works with Angular 19+
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @pegasus-heavy/ngx-tailwindcss
|
|
18
|
+
# or
|
|
19
|
+
npm install @pegasus-heavy/ngx-tailwindcss
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Peer Dependencies
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm add @angular/cdk
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Tailwind CSS Configuration
|
|
29
|
+
|
|
30
|
+
This library **does not** import Tailwind CSS directly. You must configure Tailwind in your application.
|
|
31
|
+
|
|
32
|
+
### 1. Configure Content Paths
|
|
33
|
+
|
|
34
|
+
Add the library's component templates to your Tailwind content configuration so the PostCSS parser can detect the utility classes used:
|
|
35
|
+
|
|
36
|
+
**For Tailwind CSS 4+ (CSS-based config):**
|
|
37
|
+
|
|
38
|
+
```css
|
|
39
|
+
/* app.css or styles.css */
|
|
40
|
+
@import "tailwindcss";
|
|
41
|
+
|
|
42
|
+
@source "../node_modules/@pegasus-heavy/ngx-tailwindcss/**/*.{js,mjs}";
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**For Tailwind CSS 3.x (tailwind.config.js):**
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
// tailwind.config.js
|
|
49
|
+
module.exports = {
|
|
50
|
+
content: [
|
|
51
|
+
"./src/**/*.{html,ts}",
|
|
52
|
+
"./node_modules/@pegasus-heavy/ngx-tailwindcss/**/*.{js,mjs}",
|
|
53
|
+
],
|
|
54
|
+
// ... rest of your config
|
|
55
|
+
};
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 2. Import Components
|
|
59
|
+
|
|
60
|
+
Import components directly in your Angular components:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { Component } from '@angular/core';
|
|
64
|
+
import {
|
|
65
|
+
TwButtonComponent,
|
|
66
|
+
TwCardComponent,
|
|
67
|
+
TwCardBodyDirective
|
|
68
|
+
} from '@pegasus-heavy/ngx-tailwindcss';
|
|
69
|
+
|
|
70
|
+
@Component({
|
|
71
|
+
selector: 'app-example',
|
|
72
|
+
standalone: true,
|
|
73
|
+
imports: [TwButtonComponent, TwCardComponent, TwCardBodyDirective],
|
|
74
|
+
template: `
|
|
75
|
+
<tw-card>
|
|
76
|
+
<tw-card-body>
|
|
77
|
+
<tw-button variant="primary">Click me!</tw-button>
|
|
78
|
+
</tw-card-body>
|
|
79
|
+
</tw-card>
|
|
80
|
+
`,
|
|
81
|
+
})
|
|
82
|
+
export class ExampleComponent {}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Or import everything at once:
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { TW_ALL } from '@pegasus-heavy/ngx-tailwindcss';
|
|
89
|
+
|
|
90
|
+
@Component({
|
|
91
|
+
imports: [...TW_ALL],
|
|
92
|
+
})
|
|
93
|
+
export class ExampleComponent {}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Global Configuration
|
|
97
|
+
|
|
98
|
+
Customize default styles and behavior globally:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// app.config.ts
|
|
102
|
+
import { ApplicationConfig } from '@angular/core';
|
|
103
|
+
import { provideTwConfig } from '@pegasus-heavy/ngx-tailwindcss';
|
|
104
|
+
|
|
105
|
+
export const appConfig: ApplicationConfig = {
|
|
106
|
+
providers: [
|
|
107
|
+
provideTwConfig({
|
|
108
|
+
theme: {
|
|
109
|
+
primary: 'bg-indigo-600 hover:bg-indigo-700 text-white',
|
|
110
|
+
secondary: 'bg-purple-600 hover:bg-purple-700 text-white',
|
|
111
|
+
// ... customize other variants
|
|
112
|
+
},
|
|
113
|
+
animationDuration: 300,
|
|
114
|
+
}),
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Components
|
|
120
|
+
|
|
121
|
+
### Button
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<tw-button>Default</tw-button>
|
|
125
|
+
<tw-button variant="primary">Primary</tw-button>
|
|
126
|
+
<tw-button variant="danger" size="lg">Large Danger</tw-button>
|
|
127
|
+
<tw-button variant="outline" [loading]="isLoading">Submit</tw-button>
|
|
128
|
+
<tw-button variant="ghost" [iconOnly]="true">
|
|
129
|
+
<svg twButtonIcon>...</svg>
|
|
130
|
+
</tw-button>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Props:**
|
|
134
|
+
- `variant`: `'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'ghost' | 'outline' | 'link'`
|
|
135
|
+
- `size`: `'xs' | 'sm' | 'md' | 'lg' | 'xl'`
|
|
136
|
+
- `disabled`, `loading`, `fullWidth`, `iconOnly`: `boolean`
|
|
137
|
+
- `classOverride`: Additional classes to merge
|
|
138
|
+
- `classReplace`: Complete class replacement
|
|
139
|
+
|
|
140
|
+
### Card
|
|
141
|
+
|
|
142
|
+
```html
|
|
143
|
+
<tw-card variant="elevated">
|
|
144
|
+
<tw-card-header>
|
|
145
|
+
<tw-card-title>Card Title</tw-card-title>
|
|
146
|
+
<tw-card-subtitle>Subtitle</tw-card-subtitle>
|
|
147
|
+
</tw-card-header>
|
|
148
|
+
<tw-card-body>
|
|
149
|
+
Content goes here
|
|
150
|
+
</tw-card-body>
|
|
151
|
+
<tw-card-footer>
|
|
152
|
+
<tw-button variant="primary">Action</tw-button>
|
|
153
|
+
</tw-card-footer>
|
|
154
|
+
</tw-card>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Input
|
|
158
|
+
|
|
159
|
+
```html
|
|
160
|
+
<tw-input
|
|
161
|
+
[(ngModel)]="email"
|
|
162
|
+
type="email"
|
|
163
|
+
label="Email"
|
|
164
|
+
placeholder="you@example.com"
|
|
165
|
+
hint="We'll never share your email"
|
|
166
|
+
[error]="emailError"
|
|
167
|
+
[clearable]="true">
|
|
168
|
+
</tw-input>
|
|
169
|
+
|
|
170
|
+
<tw-textarea
|
|
171
|
+
[(ngModel)]="bio"
|
|
172
|
+
label="Bio"
|
|
173
|
+
[rows]="4"
|
|
174
|
+
[maxlength]="500"
|
|
175
|
+
[showCount]="true"
|
|
176
|
+
[autoResize]="true">
|
|
177
|
+
</tw-textarea>
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Badge
|
|
181
|
+
|
|
182
|
+
```html
|
|
183
|
+
<tw-badge variant="success">Active</tw-badge>
|
|
184
|
+
<tw-badge variant="warning" badgeStyle="soft">Pending</tw-badge>
|
|
185
|
+
<tw-badge variant="danger" badgeStyle="dot">Offline</tw-badge>
|
|
186
|
+
<tw-badge variant="info" [pill]="true" [removable]="true" [remove]="onRemove">
|
|
187
|
+
Tag
|
|
188
|
+
</tw-badge>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Alert
|
|
192
|
+
|
|
193
|
+
```html
|
|
194
|
+
<tw-alert variant="success" alertStyle="soft" [dismissible]="true">
|
|
195
|
+
<tw-alert-title>Success!</tw-alert-title>
|
|
196
|
+
<tw-alert-description>Your changes have been saved.</tw-alert-description>
|
|
197
|
+
</tw-alert>
|
|
198
|
+
|
|
199
|
+
<tw-alert variant="danger" alertStyle="accent">
|
|
200
|
+
An error occurred while processing your request.
|
|
201
|
+
</tw-alert>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Modal
|
|
205
|
+
|
|
206
|
+
```html
|
|
207
|
+
<tw-button (click)="isOpen = true">Open Modal</tw-button>
|
|
208
|
+
|
|
209
|
+
<tw-modal [(open)]="isOpen" size="md">
|
|
210
|
+
<tw-modal-header>
|
|
211
|
+
<tw-modal-title>Confirm Action</tw-modal-title>
|
|
212
|
+
</tw-modal-header>
|
|
213
|
+
<tw-modal-body>
|
|
214
|
+
Are you sure you want to continue?
|
|
215
|
+
</tw-modal-body>
|
|
216
|
+
<tw-modal-footer>
|
|
217
|
+
<tw-button variant="ghost" (click)="isOpen = false">Cancel</tw-button>
|
|
218
|
+
<tw-button variant="primary" (click)="confirm()">Confirm</tw-button>
|
|
219
|
+
</tw-modal-footer>
|
|
220
|
+
</tw-modal>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Dropdown
|
|
224
|
+
|
|
225
|
+
```html
|
|
226
|
+
<tw-dropdown>
|
|
227
|
+
<button twDropdownTrigger class="px-4 py-2 bg-white border rounded-lg">
|
|
228
|
+
Options
|
|
229
|
+
</button>
|
|
230
|
+
<tw-dropdown-menu>
|
|
231
|
+
<tw-dropdown-header>Actions</tw-dropdown-header>
|
|
232
|
+
<button twDropdownItem (click)="edit()">Edit</button>
|
|
233
|
+
<button twDropdownItem (click)="duplicate()">Duplicate</button>
|
|
234
|
+
<tw-dropdown-divider></tw-dropdown-divider>
|
|
235
|
+
<button twDropdownItem class="text-rose-600">Delete</button>
|
|
236
|
+
</tw-dropdown-menu>
|
|
237
|
+
</tw-dropdown>
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Tabs
|
|
241
|
+
|
|
242
|
+
```html
|
|
243
|
+
<tw-tabs [(value)]="activeTab" variant="line">
|
|
244
|
+
<tw-tab-panel value="overview" label="Overview">
|
|
245
|
+
Overview content
|
|
246
|
+
</tw-tab-panel>
|
|
247
|
+
<tw-tab-panel value="settings" label="Settings">
|
|
248
|
+
Settings content
|
|
249
|
+
</tw-tab-panel>
|
|
250
|
+
<tw-tab-panel value="billing" label="Billing" [disabled]="!isPremium">
|
|
251
|
+
Billing content
|
|
252
|
+
</tw-tab-panel>
|
|
253
|
+
</tw-tabs>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Directives
|
|
257
|
+
|
|
258
|
+
### Ripple Effect
|
|
259
|
+
|
|
260
|
+
```html
|
|
261
|
+
<button twRipple class="px-4 py-2 bg-blue-600 text-white rounded">
|
|
262
|
+
Click me
|
|
263
|
+
</button>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Tooltip
|
|
267
|
+
|
|
268
|
+
```html
|
|
269
|
+
<button twTooltip="Save changes" tooltipPosition="top">
|
|
270
|
+
Save
|
|
271
|
+
</button>
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Click Outside
|
|
275
|
+
|
|
276
|
+
```html
|
|
277
|
+
<div (twClickOutside)="closeMenu()" [clickOutsideEnabled]="isMenuOpen">
|
|
278
|
+
Menu content
|
|
279
|
+
</div>
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Focus Trap
|
|
283
|
+
|
|
284
|
+
```html
|
|
285
|
+
<div twFocusTrap [focusTrapAutoFocus]="true">
|
|
286
|
+
<input type="text">
|
|
287
|
+
<button>Submit</button>
|
|
288
|
+
</div>
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Class Merge
|
|
292
|
+
|
|
293
|
+
```html
|
|
294
|
+
<!-- Intelligently merges Tailwind classes, resolving conflicts -->
|
|
295
|
+
<div [twClass]="'px-4 py-2 bg-blue-500'" [twClassMerge]="'px-8 bg-red-500'">
|
|
296
|
+
Will have px-8 py-2 bg-red-500
|
|
297
|
+
</div>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Customization Examples
|
|
301
|
+
|
|
302
|
+
### Per-Component Override
|
|
303
|
+
|
|
304
|
+
```html
|
|
305
|
+
<tw-button
|
|
306
|
+
variant="primary"
|
|
307
|
+
classOverride="bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600">
|
|
308
|
+
Gradient Button
|
|
309
|
+
</tw-button>
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Complete Class Replacement
|
|
313
|
+
|
|
314
|
+
```html
|
|
315
|
+
<tw-button classReplace="your-completely-custom-classes">
|
|
316
|
+
Custom Styled
|
|
317
|
+
</tw-button>
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Using the Class Service
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
import { TwClassService } from '@pegasus-heavy/ngx-tailwindcss';
|
|
324
|
+
|
|
325
|
+
@Component({...})
|
|
326
|
+
export class MyComponent {
|
|
327
|
+
private twClass = inject(TwClassService);
|
|
328
|
+
|
|
329
|
+
get buttonClasses() {
|
|
330
|
+
return this.twClass.merge(
|
|
331
|
+
'px-4 py-2 rounded',
|
|
332
|
+
this.isPrimary ? 'bg-blue-600 text-white' : 'bg-gray-100',
|
|
333
|
+
this.isDisabled && 'opacity-50 cursor-not-allowed'
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## License
|
|
340
|
+
|
|
341
|
+
MIT © Pegasus Heavy Industries LLC
|
|
342
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pegasusheavy/ngx-tailwindcss",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "A highly customizable Angular component library for Tailwind CSS 4+. Build beautiful, accessible UI components with full theming support, intelligent class merging, and zero bundled CSS. Features 30+ components including buttons, cards, modals, forms, tables, and more.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Pegasus Heavy Industries LLC",
|
|
9
|
+
"url": "https://pegasusheavy.github.io/ngx-tailwindcss"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://pegasusheavy.github.io/ngx-tailwindcss",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/pegasusheavy/ngx-tailwindcss.git"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/pegasusheavy/ngx-tailwindcss/issues"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"angular",
|
|
21
|
+
"tailwindcss",
|
|
22
|
+
"tailwind",
|
|
23
|
+
"tailwind-css-4",
|
|
24
|
+
"components",
|
|
25
|
+
"ui",
|
|
26
|
+
"ui-library",
|
|
27
|
+
"ui-components",
|
|
28
|
+
"component-library",
|
|
29
|
+
"angular-components",
|
|
30
|
+
"angular-library",
|
|
31
|
+
"angular-ui",
|
|
32
|
+
"design-system",
|
|
33
|
+
"typescript",
|
|
34
|
+
"standalone-components",
|
|
35
|
+
"signals",
|
|
36
|
+
"accessible",
|
|
37
|
+
"accessibility",
|
|
38
|
+
"a11y",
|
|
39
|
+
"aria",
|
|
40
|
+
"wcag",
|
|
41
|
+
"screen-reader",
|
|
42
|
+
"i18n",
|
|
43
|
+
"internationalization",
|
|
44
|
+
"localization",
|
|
45
|
+
"l10n",
|
|
46
|
+
"rtl",
|
|
47
|
+
"translations",
|
|
48
|
+
"responsive",
|
|
49
|
+
"customizable",
|
|
50
|
+
"theming",
|
|
51
|
+
"forms",
|
|
52
|
+
"buttons",
|
|
53
|
+
"modals",
|
|
54
|
+
"cards",
|
|
55
|
+
"tables",
|
|
56
|
+
"dropdown",
|
|
57
|
+
"toast",
|
|
58
|
+
"accordion",
|
|
59
|
+
"tabs",
|
|
60
|
+
"pagination",
|
|
61
|
+
"avatar",
|
|
62
|
+
"badge",
|
|
63
|
+
"spinner",
|
|
64
|
+
"skeleton",
|
|
65
|
+
"progress",
|
|
66
|
+
"tree",
|
|
67
|
+
"timeline",
|
|
68
|
+
"stepper"
|
|
69
|
+
],
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"@angular/animations": "^19.0.0 || ^20.0.0 || ^21.0.0",
|
|
72
|
+
"@angular/cdk": "^19.0.0 || ^20.0.0 || ^21.0.0",
|
|
73
|
+
"@angular/common": "^19.0.0 || ^20.0.0 || ^21.0.0",
|
|
74
|
+
"@angular/core": "^19.0.0 || ^20.0.0 || ^21.0.0",
|
|
75
|
+
"@angular/forms": "^19.0.0 || ^20.0.0 || ^21.0.0"
|
|
76
|
+
},
|
|
77
|
+
"devDependencies": {
|
|
78
|
+
"@analogjs/vite-plugin-angular": "^2.1.3",
|
|
79
|
+
"@angular-devkit/build-angular": "^20.0.0",
|
|
80
|
+
"@angular/animations": "^20.0.0",
|
|
81
|
+
"@angular/build": "^20.0.0",
|
|
82
|
+
"@angular/cdk": "^20.0.0",
|
|
83
|
+
"@angular/cli": "^20.0.0",
|
|
84
|
+
"@angular/common": "^20.0.0",
|
|
85
|
+
"@angular/compiler": "^20.0.0",
|
|
86
|
+
"@angular/compiler-cli": "^20.0.0",
|
|
87
|
+
"@angular/core": "^20.0.0",
|
|
88
|
+
"@angular/forms": "^20.0.0",
|
|
89
|
+
"@angular/platform-browser": "^20.0.0",
|
|
90
|
+
"@angular/platform-browser-dynamic": "^20.0.0",
|
|
91
|
+
"@eslint/js": "^9.0.0",
|
|
92
|
+
"@pegasusheavy/eslint-typescript-access": "^1.0.0",
|
|
93
|
+
"@testing-library/angular": "^17.0.0",
|
|
94
|
+
"@testing-library/dom": "^10.0.0",
|
|
95
|
+
"@testing-library/jest-dom": "^6.0.0",
|
|
96
|
+
"@testing-library/user-event": "^14.0.0",
|
|
97
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
98
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
99
|
+
"@typescript-eslint/utils": "^8.0.0",
|
|
100
|
+
"@vitest/coverage-v8": "^3.0.0",
|
|
101
|
+
"angular-eslint": "^19.0.0",
|
|
102
|
+
"concurrently": "^9.0.0",
|
|
103
|
+
"eslint": "^9.0.0",
|
|
104
|
+
"eslint-config-prettier": "^9.1.0",
|
|
105
|
+
"eslint-plugin-jsdoc": "^50.0.0",
|
|
106
|
+
"eslint-plugin-unicorn": "^56.0.0",
|
|
107
|
+
"jsdom": "^26.0.0",
|
|
108
|
+
"ng-packagr": "^20.0.0",
|
|
109
|
+
"prettier": "^3.4.0",
|
|
110
|
+
"rxjs": "~7.8.0",
|
|
111
|
+
"tslib": "^2.6.0",
|
|
112
|
+
"typescript": "~5.8.0",
|
|
113
|
+
"typescript-eslint": "^8.0.0",
|
|
114
|
+
"vitest": "^3.0.0",
|
|
115
|
+
"zone.js": "~0.15.0",
|
|
116
|
+
"@commitlint/cli": "^18.1.0",
|
|
117
|
+
"@commitlint/config-conventional": "^18.0.0",
|
|
118
|
+
"husky": "^9.0.0"
|
|
119
|
+
},
|
|
120
|
+
"exports": {
|
|
121
|
+
".": {
|
|
122
|
+
"types": "./index.d.ts",
|
|
123
|
+
"default": "./fesm2022/pegasus-heavy-ngx-tailwindcss.mjs"
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"sideEffects": false,
|
|
127
|
+
"scripts": {
|
|
128
|
+
"ng": "ng",
|
|
129
|
+
"build": "ng build ngx-tailwindcss --configuration production",
|
|
130
|
+
"build:watch": "ng build ngx-tailwindcss --watch",
|
|
131
|
+
"dev": "concurrently -n lib,docs -c cyan,green \"pnpm run build:watch\" \"pnpm run docs:dev\"",
|
|
132
|
+
"docs:dev": "cd docs && pnpm run dev",
|
|
133
|
+
"docs:start": "cd docs && pnpm run start",
|
|
134
|
+
"test": "vitest",
|
|
135
|
+
"test:run": "vitest run",
|
|
136
|
+
"test:coverage": "vitest run --coverage",
|
|
137
|
+
"test:ui": "vitest --ui",
|
|
138
|
+
"lint": "eslint projects/",
|
|
139
|
+
"lint:fix": "eslint projects/ --fix",
|
|
140
|
+
"format": "prettier --write \"projects/**/*.{ts,html,scss,css,json}\"",
|
|
141
|
+
"format:check": "prettier --check \"projects/**/*.{ts,html,scss,css,json}\"",
|
|
142
|
+
"commitlint": "commitlint"
|
|
143
|
+
}
|
|
144
|
+
}
|