wally-ui 1.4.0 → 1.5.1

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/README.md CHANGED
@@ -1,79 +1,161 @@
1
1
  # Wally UI
2
2
 
3
- A modern Angular component library built with standalone components and Tailwind CSS. Wally UI provides a collection of reusable, accessible components that integrate seamlessly into your Angular applications.
3
+ > A modern Angular component library built with standalone components, Tailwind CSS, and enterprise-grade accessibility.
4
4
 
5
- **[Live Demo](https://wally-ui.com/)**
5
+ [![npm version](https://img.shields.io/npm/v/wally-ui.svg)](https://www.npmjs.com/package/wally-ui)
6
+ [![MIT License](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
6
7
 
7
- ## Features
8
+ **[Live Demo & Documentation](https://wally-ui.com/)**
8
9
 
9
- - Built for Angular 17+ with standalone component architecture
10
- - Server-Side Rendering (SSR) support
11
- - Dark mode support out of the box
12
- - Tailwind CSS v3/v4 styling
13
- - TypeScript interfaces and type safety
14
- - Individual component installation
15
- - Zero configuration setup
10
+ ## Why Wally UI?
11
+
12
+ - **Zero Configuration**: Install components individually - no bloated bundles
13
+ - **Accessibility First**: Enterprise-grade a11y with ARIA support and screen reader compatibility
14
+ - **Dark Mode Native**: Complete light/dark theme support out of the box
15
+ - **SSR Ready**: Full Server-Side Rendering support for performance
16
+ - **Tailwind Powered**: Beautiful, customizable styling with Tailwind CSS v3/v4
16
17
 
17
18
  ## Requirements
18
19
 
19
- - Angular 17+ (required for standalone component support)
20
- - Tailwind CSS v3 or v4
21
- - Node.js 18+
20
+ - **Tailwind CSS v3 or v4**
21
+ - **Node.js 18+**
22
+
23
+ ## 📦 Available Components
22
24
 
23
- ## Installation
25
+ | Component | Status | Description |
26
+ |-----------|--------|-------------|
27
+ | **Input** | ✅ **New** | Full-featured input with validation, loading states, and FormGroup support |
28
+ | **Button** | 🚧 Under Construction | Versatile button with loading states and notifications |
29
+ | **Breadcrumb** | 🚧 Under Construction | Navigation breadcrumb component |
24
30
 
25
- Install components individually using the CLI:
31
+ ## 🚀 Quick Start
26
32
 
33
+ ### 1. Install a component
27
34
  ```bash
28
- # Install specific component
35
+ # Install the Input component (recommended for forms)
36
+ npx wally-ui add input
37
+
38
+ # Install other components
29
39
  npx wally-ui add button
30
40
 
31
41
  # List all available components
32
42
  npx wally-ui list
33
43
  ```
34
44
 
45
+ ### 2. Import and use in your Angular component
46
+ ```typescript
47
+ import { Component } from '@angular/core';
48
+ import { Input } from './components/wally-ui/input/input';
49
+
50
+ @Component({
51
+ selector: 'app-example',
52
+ imports: [Input], // Standalone component import
53
+ template: `
54
+ <wally-input
55
+ label="Email Address"
56
+ type="email"
57
+ placeholder="Enter your email">
58
+ </wally-input>
59
+ `
60
+ })
61
+ export class ExampleComponent {}
62
+ ```
63
+
64
+ ### 3. For reactive forms (recommended)
65
+ ```typescript
66
+ import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
67
+ import { Input } from './components/wally-ui/input/input';
68
+
69
+ @Component({
70
+ imports: [Input, ReactiveFormsModule],
71
+ template: `
72
+ <form [formGroup]="userForm">
73
+ <wally-input
74
+ formControlName="email"
75
+ label="Email"
76
+ type="email"
77
+ [valid]="isFieldValid('email')"
78
+ [errorMessage]="getFieldError('email')">
79
+ </wally-input>
80
+ </form>
81
+ `
82
+ })
83
+ export class FormComponent {
84
+ userForm = this.fb.group({
85
+ email: ['', [Validators.required, Validators.email]]
86
+ });
87
+ }
88
+ ```
89
+
35
90
  ## Project Structure
36
91
 
37
- When installing a component, Wally UI creates the following structure:
92
+ Components are installed directly into your project with zero dependencies:
38
93
 
39
94
  ```
40
- src/
41
- └── app/
42
- └── components/
43
- └── wally-ui/
44
- └── button/
45
- ├── button.ts
46
- └── button.html
95
+ src/app/components/wally-ui/
96
+ ├── input/
97
+ │ ├── input.ts # Component logic with Angular signals
98
+ └── input.html # Template with Tailwind styling
99
+ └── button/
100
+ ├── button.ts
101
+ └── button.html
47
102
  ```
48
103
 
49
- ## Quick Start
104
+ ## Features Showcase
50
105
 
51
- 1. Install a component:
52
- ```bash
53
- npx wally-ui add button
54
- ```
106
+ ### Input Component (v1.5.0)
107
+ ```html
108
+ <!-- All input states supported -->
109
+ <wally-input label="Username" placeholder="Enter username"></wally-input>
110
+ <wally-input [loading]="true" placeholder="Processing..."></wally-input>
111
+ <wally-input [valid]="true" placeholder="Valid input"></wally-input>
112
+ <wally-input errorMessage="Field is required"></wally-input>
113
+ <wally-input [disabled]="true" placeholder="Disabled input"></wally-input>
55
114
 
56
- 2. Import and use in your component:
57
- ```typescript
58
- import { Component } from '@angular/core';
59
- import { Button } from './components/wally-ui/button/button';
115
+ <!-- Password with toggle -->
116
+ <wally-input type="password" label="Password"></wally-input>
60
117
 
61
- @Component({
62
- selector: 'app-example',
63
- imports: [Button],
64
- template: `<wally-button>Click me</wally-button>`
65
- })
66
- export class ExampleComponent {}
118
+ <!-- FormGroup integration -->
119
+ <wally-input formControlName="email" type="email"></wally-input>
67
120
  ```
68
121
 
69
- ## Development Status
122
+ **Features:**
123
+ - ✅ Complete ControlValueAccessor implementation
124
+ - ✅ Angular Signals architecture (Angular 20+ optimized)
125
+ - ✅ Loading, valid, error, disabled states
126
+ - ✅ Password visibility toggle
127
+ - ✅ Full accessibility (ARIA attributes, screen readers)
128
+ - ✅ Dark mode support
129
+ - ✅ TypeScript interfaces
130
+
131
+ ## AI Assistant Ready
132
+
133
+ This library is designed to work seamlessly with AI coding assistants:
70
134
 
71
- Wally UI is currently in experimental development. Components are being actively developed and new features are continuously added. More components will be available soon.
135
+ - **Clear Documentation**: Comprehensive examples and API references
136
+ - **Semantic Naming**: Intuitive component and property names
137
+ - **Copy-Paste Ready**: All examples work out of the box
138
+ - **IntelliSense**: Full TypeScript support for autocomplete
72
139
 
73
- ## Documentation
140
+ ## Documentation & Examples
74
141
 
75
- Visit [wally-ui.com](https://wally-ui.com/) for complete documentation, examples, and component API references.
142
+ - **[Complete Documentation](https://wally-ui.com/documentation)**
143
+ - **[Component Examples](https://wally-ui.com/documentation/components)**
144
+ - **[Live Playground](https://wally-ui.com/)**
145
+
146
+ ## Roadmap
147
+
148
+ - [ ] **Select Component** - Dropdown with search and multi-select
149
+ - [ ] **Modal Component** - Overlay dialogs and popups
150
+ - [ ] **Table Component** - Data tables with sorting and pagination
151
+ - [ ] **Form Component** - Complete form wrapper with validation
152
+ - [ ] **Card Component** - Content containers
153
+ - [ ] **Badge Component** - Status indicators
76
154
 
77
155
  ## License
78
156
 
79
- MIT
157
+ MIT © [Walisson Carvalho](https://github.com/walissoncarvalho)
158
+
159
+ ---
160
+
161
+ **Built with for the Angular community**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wally-ui",
3
- "version": "1.4.0",
3
+ "version": "1.5.1",
4
4
  "description": "About Where’s Wally? Right here — bringing you ready-to-use Angular components with Wally-UI. Stop searching, start building.",
5
5
  "bin": {
6
6
  "wally": "dist/cli.js"
@@ -11,4 +11,7 @@ User-agent: claudebot
11
11
  Allow: /
12
12
 
13
13
  User-agent: ChatGPT-User
14
- Allow: /
14
+ Allow: /
15
+
16
+ # Sitemap location
17
+ Sitemap: https://wally-ui.com/sitemap.xml
@@ -0,0 +1,47 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
5
+ http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
6
+
7
+ <!-- Homepage -->
8
+ <url>
9
+ <loc>https://wally-ui.com/</loc>
10
+ <lastmod>2025-01-25</lastmod>
11
+ <changefreq>weekly</changefreq>
12
+ <priority>1.0</priority>
13
+ </url>
14
+
15
+ <!-- Documentation Index -->
16
+ <url>
17
+ <loc>https://wally-ui.com/documentation</loc>
18
+ <lastmod>2025-01-25</lastmod>
19
+ <changefreq>weekly</changefreq>
20
+ <priority>0.9</priority>
21
+ </url>
22
+
23
+ <!-- Components Index -->
24
+ <url>
25
+ <loc>https://wally-ui.com/documentation/components</loc>
26
+ <lastmod>2025-09-25</lastmod>
27
+ <changefreq>weekly</changefreq>
28
+ <priority>0.9</priority>
29
+ </url>
30
+
31
+ <!-- Button Documentation -->
32
+ <url>
33
+ <loc>https://wally-ui.com/documentation/components/button</loc>
34
+ <lastmod>2025-09-25</lastmod>
35
+ <changefreq>monthly</changefreq>
36
+ <priority>0.8</priority>
37
+ </url>
38
+
39
+ <!-- Input Documentation -->
40
+ <url>
41
+ <loc>https://wally-ui.com/documentation/components/input</loc>
42
+ <lastmod>2025-09-25</lastmod>
43
+ <changefreq>monthly</changefreq>
44
+ <priority>0.8</priority>
45
+ </url>
46
+
47
+ </urlset>
@@ -1,5 +1,5 @@
1
1
  @if (label()) {
2
- <div class="py-1">
2
+ <div class="py-2">
3
3
  <label [for]="inputId" class="block text-sm font-medium text-[#0a0a0a] dark:text-white">
4
4
  {{ label() }}
5
5
  </label>
@@ -7,8 +7,9 @@
7
7
  }
8
8
 
9
9
  <div class="relative">
10
- <input [id]="inputId" [type]="currentInputType()" [value]="value()" [disabled]="disabled || loading()"
11
- [placeholder]="placeholder()" [autocomplete]="autocomplete() || (type() === 'password' ? 'new-password' : '')" class="
10
+ <input [id]="inputId" [type]="currentInputType()" [value]="value()" [disabled]="isDisabled() || loading()"
11
+ [placeholder]="placeholder()" [autocomplete]="autocomplete() || (type() === 'password' ? 'new-password' : '')"
12
+ [attr.aria-describedby]="errorId()" [attr.aria-invalid]="!!errorMessage()" class="
12
13
  font-semibold
13
14
  block
14
15
  w-full
@@ -18,7 +19,7 @@
18
19
  focus:outline-none focus:ring-2 focus:ring-neutral-300
19
20
  bg-gray-100
20
21
  dark:bg-[#1b1b1b] dark:text-white dark:placeholder:text-neutral-500 dark:focus:ring-neutral-700
21
- disabled:opacity-80 disabled:pointer-events-none
22
+ disabled:opacity-70 disabled:pointer-events-none disabled:cursor-not-allowed
22
23
  transition duration-200 ease-in-out
23
24
  py-4 px-4" [ngClass]="{
24
25
  'pe-12': type() === 'password',
@@ -62,7 +63,7 @@
62
63
  </div>
63
64
 
64
65
  @if (errorMessage()) {
65
- <div class="py-1">
66
+ <div class="py-1" [id]="inputId + '-error'">
66
67
  <span class="text-sm text-red-500 font-medium">
67
68
  {{ errorMessage() }}
68
69
  </span>
@@ -32,9 +32,17 @@ export class Input implements ControlValueAccessor {
32
32
  valid: InputSignal<boolean> = input<boolean>(false);
33
33
  errorMessage: InputSignal<string> = input<string>('');
34
34
  loading: InputSignal<boolean> = input<boolean>(false);
35
+ disabled: InputSignal<boolean> = input<boolean>(false);
35
36
 
36
37
  protected readonly showPassword = signal<boolean>(false);
37
38
  protected readonly inputId = `wally-input-${Math.random().toString(36).substring(2, 11)}`;
39
+ protected readonly errorId = computed(() =>
40
+ this.errorMessage() ? `${this.inputId}-error` : undefined
41
+ );
42
+
43
+ protected readonly isDisabled = computed(() =>
44
+ this.disabled() || this.internalDisabled()
45
+ );
38
46
 
39
47
  private touched: WritableSignal<boolean> = signal<boolean>(false);
40
48
  value: WritableSignal<string> = signal<string>('');
@@ -53,7 +61,7 @@ export class Input implements ControlValueAccessor {
53
61
  return 'password';
54
62
  });
55
63
 
56
- disabled: boolean = false;
64
+ private internalDisabled = signal<boolean>(false);
57
65
 
58
66
  private onChange = (value: any) => { };
59
67
  private onTouched = () => { };
@@ -73,7 +81,7 @@ export class Input implements ControlValueAccessor {
73
81
  }
74
82
 
75
83
  setDisabledState?(isDisabled: boolean): void {
76
- this.disabled = isDisabled;
84
+ this.internalDisabled.set(isDisabled);
77
85
  }
78
86
 
79
87
  togglePasswordVisibility(): void {
@@ -50,7 +50,7 @@
50
50
  <div class="bg-gray-200 dark:bg-[#121212] rounded-lg p-4">
51
51
  <div class="flex items-center gap-2 mb-2">
52
52
  <h4 class="text-md font-semibold text-[#0a0a0a] dark:text-white">Input</h4>
53
- <span class="text-xs bg-yellow-500 text-black px-2 py-1 rounded">Under Construction</span>
53
+ <span class="text-xs bg-blue-500 text-white px-2 py-1 rounded">New</span>
54
54
  </div>
55
55
  <p class="text-sm text-gray-700 dark:text-gray-400 mb-3">
56
56
  A versatile input component with full FormGroup support, perfect for forms and data entry.
@@ -76,6 +76,7 @@ onSubmit() {
76
76
  loadingState: `<wally-input [loading]="true" placeholder="Loading..."></wally-input>`,
77
77
  validState: `<wally-input [valid]="true" placeholder="Valid input"></wally-input>`,
78
78
  errorState: `<wally-input errorMessage="This field is required" placeholder="Enter value"></wally-input>`,
79
+ disabledState: `<wally-input [disabled]="true" placeholder="Disabled input"></wally-input>`,
79
80
  passwordWithToggle: `<wally-input type="password" label="Password" placeholder="Enter secure password"></wally-input>`,
80
81
 
81
82
  // Properties
@@ -84,5 +85,6 @@ onSubmit() {
84
85
  propertyPlaceholder: `placeholder: string = '';`,
85
86
  propertyLoading: `loading: boolean = false;`,
86
87
  propertyValid: `valid: boolean = false;`,
87
- propertyError: `errorMessage: string = '';`
88
+ propertyError: `errorMessage: string = '';`,
89
+ propertyDisabled: `disabled: boolean = false;`
88
90
  };
@@ -11,13 +11,6 @@
11
11
  A fully-featured input component with label support, loading states, validation styling, and complete FormGroup integration.
12
12
  </p>
13
13
 
14
- <!-- Under Construction Badge -->
15
- <div class="mb-6">
16
- <span class="text-xs bg-yellow-500 text-black px-3 py-1 rounded-full font-medium">Under Construction</span>
17
- <p class="text-sm text-gray-600 dark:text-gray-400 mt-2">
18
- This component is actively being developed. More features and improvements coming soon!
19
- </p>
20
- </div>
21
14
 
22
15
  <!-- AI Prompts -->
23
16
  <div class="flex flex-wrap gap-2 mb-6">
@@ -67,6 +60,10 @@
67
60
  <wally-input label="Full Name" placeholder="Enter your name"></wally-input>
68
61
  <wally-input label="Email Address" type="email" placeholder="Enter your email"></wally-input>
69
62
  <wally-input label="Password" type="password" placeholder="Enter password"></wally-input>
63
+ <wally-input label="Loading State" [loading]="true" placeholder="Processing..."></wally-input>
64
+ <wally-input label="Valid State" [valid]="true" placeholder="Valid input"></wally-input>
65
+ <wally-input label="Error State" errorMessage="This field is required" placeholder="Invalid input"></wally-input>
66
+ <wally-input label="Disabled State" [disabled]="true" placeholder="Disabled input"></wally-input>
70
67
  </div>
71
68
  </form>
72
69
  </div>
@@ -211,6 +208,17 @@
211
208
  </div>
212
209
  </div>
213
210
 
211
+ <!-- Disabled State -->
212
+ <div>
213
+ <h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">Disabled State</h3>
214
+ <div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg mb-4">
215
+ <pre><code [innerHTML]="disabledCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
216
+ </div>
217
+ <div class="p-6 border rounded-lg bg-white dark:bg-[#121212]">
218
+ <wally-input label="Username" [disabled]="true" placeholder="Disabled input"></wally-input>
219
+ </div>
220
+ </div>
221
+
214
222
  <!-- Password with Toggle -->
215
223
  <div>
216
224
  <h3 class="text-md font-medium mb-3 text-[#0a0a0a] dark:text-white">Password with Toggle</h3>
@@ -323,6 +331,13 @@
323
331
  </div>
324
332
  <p class="text-sm text-gray-700 dark:text-gray-400">Error message text - shows red styling and displays error below input</p>
325
333
  </div>
334
+
335
+ <div class="space-y-2">
336
+ <div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
337
+ <pre><code [innerHTML]="propertyDisabledCode" class="text-sm text-[#0a0a0a] dark:text-white"></code></pre>
338
+ </div>
339
+ <p class="text-sm text-gray-700 dark:text-gray-400">Disables the input when true - shows visual disabled state and prevents interaction</p>
340
+ </div>
326
341
  </div>
327
342
  </section>
328
343
 
@@ -333,21 +348,11 @@
333
348
  <div class="space-y-4">
334
349
  <div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
335
350
  <div class="flex items-center gap-2 mb-2">
336
- <h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Input Icons</h3>
337
- <span class="text-xs bg-blue-500 text-white px-2 py-1 rounded">Coming Soon</span>
338
- </div>
339
- <p class="text-sm text-gray-700 dark:text-gray-400">
340
- Support for custom icons on the left and right sides of the input.
341
- </p>
342
- </div>
343
-
344
- <div class="bg-gray-200 dark:bg-[#121212] p-4 rounded-lg">
345
- <div class="flex items-center gap-2 mb-2">
346
- <h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Input Sizes</h3>
351
+ <h3 class="text-md font-medium text-[#0a0a0a] dark:text-white">Styles-Only Directive</h3>
347
352
  <span class="text-xs bg-blue-500 text-white px-2 py-1 rounded">Coming Soon</span>
348
353
  </div>
349
354
  <p class="text-sm text-gray-700 dark:text-gray-400">
350
- Different input sizes: small, medium, large for various layouts.
355
+ A lightweight directive for developers who want only the input styling without the full component logic.
351
356
  </p>
352
357
  </div>
353
358
  </div>
@@ -61,6 +61,7 @@ export class InputDocs {
61
61
  loadingCode = getFormattedCode(InputCodeExamples.loadingState, 'html');
62
62
  validCode = getFormattedCode(InputCodeExamples.validState, 'html');
63
63
  errorCode = getFormattedCode(InputCodeExamples.errorState, 'html');
64
+ disabledCode = getFormattedCode(InputCodeExamples.disabledState, 'html');
64
65
  passwordCode = getFormattedCode(InputCodeExamples.passwordWithToggle, 'html');
65
66
 
66
67
  // Properties
@@ -70,6 +71,7 @@ export class InputDocs {
70
71
  propertyLoadingCode = getFormattedCode(InputCodeExamples.propertyLoading, 'typescript');
71
72
  propertyValidCode = getFormattedCode(InputCodeExamples.propertyValid, 'typescript');
72
73
  propertyErrorCode = getFormattedCode(InputCodeExamples.propertyError, 'typescript');
74
+ propertyDisabledCode = getFormattedCode(InputCodeExamples.propertyDisabled, 'typescript');
73
75
 
74
76
  constructor(
75
77
  private aiPromptService: AiPromptService,