Added extensive component library with feedback components (empty state, loading spinner, skeleton loader), enhanced form components (autocomplete, date picker, file upload, form field, time picker), navigation components (pagination), and overlay components (backdrop, drawer, modal, overlay container). Updated demo application with comprehensive showcase components and enhanced styling throughout the project. Excluded font files from repository to reduce size. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
680 lines
23 KiB
TypeScript
680 lines
23 KiB
TypeScript
import { Component, ChangeDetectionStrategy, signal } from '@angular/core';
|
|
import { CommonModule } from '@angular/common';
|
|
import { FormsModule } from '@angular/forms';
|
|
import { TextInputComponent } from '../../../../../ui-essentials/src/lib/components/forms/input';
|
|
import { TextareaComponent } from '../../../../../ui-essentials/src/lib/components/forms/input';
|
|
import { InputWrapperComponent } from '../../../../../ui-essentials/src/lib/components/forms/input';
|
|
import { faSearch, faEnvelope, faEdit } from '@fortawesome/free-solid-svg-icons';
|
|
|
|
@Component({
|
|
selector: 'ui-input-demo',
|
|
standalone: true,
|
|
imports: [
|
|
CommonModule,
|
|
FormsModule,
|
|
TextInputComponent,
|
|
TextareaComponent,
|
|
InputWrapperComponent
|
|
],
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
template: `
|
|
<div style="padding: 2rem;">
|
|
<h2>Input Component Showcase</h2>
|
|
|
|
<!-- Text Input Variants -->
|
|
<section style="margin-bottom: 3rem;">
|
|
<h3>Text Input Variants</h3>
|
|
|
|
<!-- Outlined Variant -->
|
|
<div style="margin-bottom: 2rem;">
|
|
<h4>Outlined (Default)</h4>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem;">
|
|
<ui-text-input
|
|
label="Small Outlined"
|
|
placeholder="Enter text..."
|
|
size="sm"
|
|
variant="outlined"
|
|
[(ngModel)]="textValues['outlined-sm']"
|
|
(inputChange)="handleInputChange('outlined-sm', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Medium Outlined"
|
|
placeholder="Enter text..."
|
|
size="md"
|
|
variant="outlined"
|
|
[(ngModel)]="textValues['outlined-md']"
|
|
(inputChange)="handleInputChange('outlined-md', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Large Outlined"
|
|
placeholder="Enter text..."
|
|
size="lg"
|
|
variant="outlined"
|
|
[(ngModel)]="textValues['outlined-lg']"
|
|
(inputChange)="handleInputChange('outlined-lg', $event)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filled Variant -->
|
|
<div style="margin-bottom: 2rem;">
|
|
<h4>Filled</h4>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem;">
|
|
<ui-text-input
|
|
label="Small Filled"
|
|
placeholder="Enter text..."
|
|
size="sm"
|
|
variant="filled"
|
|
[(ngModel)]="textValues['filled-sm']"
|
|
(inputChange)="handleInputChange('filled-sm', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Medium Filled"
|
|
placeholder="Enter text..."
|
|
size="md"
|
|
variant="filled"
|
|
[(ngModel)]="textValues['filled-md']"
|
|
(inputChange)="handleInputChange('filled-md', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Large Filled"
|
|
placeholder="Enter text..."
|
|
size="lg"
|
|
variant="filled"
|
|
[(ngModel)]="textValues['filled-lg']"
|
|
(inputChange)="handleInputChange('filled-lg', $event)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Underlined Variant -->
|
|
<div style="margin-bottom: 2rem;">
|
|
<h4>Underlined</h4>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem;">
|
|
<ui-text-input
|
|
label="Small Underlined"
|
|
placeholder="Enter text..."
|
|
size="sm"
|
|
variant="underlined"
|
|
[(ngModel)]="textValues['underlined-sm']"
|
|
(inputChange)="handleInputChange('underlined-sm', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Medium Underlined"
|
|
placeholder="Enter text..."
|
|
size="md"
|
|
variant="underlined"
|
|
[(ngModel)]="textValues['underlined-md']"
|
|
(inputChange)="handleInputChange('underlined-md', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Large Underlined"
|
|
placeholder="Enter text..."
|
|
size="lg"
|
|
variant="underlined"
|
|
[(ngModel)]="textValues['underlined-lg']"
|
|
(inputChange)="handleInputChange('underlined-lg', $event)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Input Types -->
|
|
<section style="margin-bottom: 3rem;">
|
|
<h3>Input Types</h3>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem;">
|
|
<ui-text-input
|
|
label="Email Input"
|
|
placeholder="email@example.com"
|
|
type="email"
|
|
variant="outlined"
|
|
[(ngModel)]="textValues['email']"
|
|
(inputChange)="handleInputChange('email', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Password Input"
|
|
placeholder="Enter password"
|
|
type="password"
|
|
variant="outlined"
|
|
[(ngModel)]="textValues['password']"
|
|
(inputChange)="handleInputChange('password', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Search Input"
|
|
placeholder="Search..."
|
|
type="search"
|
|
variant="outlined"
|
|
[(ngModel)]="textValues['search']"
|
|
(inputChange)="handleInputChange('search', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Number Input"
|
|
placeholder="Enter number"
|
|
type="number"
|
|
variant="outlined"
|
|
min="0"
|
|
max="100"
|
|
step="1"
|
|
[(ngModel)]="textValues['number']"
|
|
(inputChange)="handleInputChange('number', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Tel Input"
|
|
placeholder="+1 (555) 000-0000"
|
|
type="tel"
|
|
variant="outlined"
|
|
[(ngModel)]="textValues['tel']"
|
|
(inputChange)="handleInputChange('tel', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="URL Input"
|
|
placeholder="https://example.com"
|
|
type="url"
|
|
variant="outlined"
|
|
[(ngModel)]="textValues['url']"
|
|
(inputChange)="handleInputChange('url', $event)"
|
|
/>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Input States -->
|
|
<section style="margin-bottom: 3rem;">
|
|
<h3>Input States</h3>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem;">
|
|
<ui-text-input
|
|
label="Default State"
|
|
placeholder="Enter text..."
|
|
variant="outlined"
|
|
state="default"
|
|
helperText="This is helper text"
|
|
[(ngModel)]="textValues['state-default']"
|
|
(inputChange)="handleInputChange('state-default', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Error State"
|
|
placeholder="Enter text..."
|
|
variant="outlined"
|
|
state="error"
|
|
errorMessage="This field has an error"
|
|
[(ngModel)]="textValues['state-error']"
|
|
(inputChange)="handleInputChange('state-error', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Success State"
|
|
placeholder="Enter text..."
|
|
variant="outlined"
|
|
state="success"
|
|
helperText="Input is valid!"
|
|
[(ngModel)]="textValues['state-success']"
|
|
(inputChange)="handleInputChange('state-success', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Warning State"
|
|
placeholder="Enter text..."
|
|
variant="outlined"
|
|
state="warning"
|
|
helperText="Please double-check this value"
|
|
[(ngModel)]="textValues['state-warning']"
|
|
(inputChange)="handleInputChange('state-warning', $event)"
|
|
/>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Inputs with Icons and Features -->
|
|
<section style="margin-bottom: 3rem;">
|
|
<h3>Inputs with Icons and Features</h3>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem;">
|
|
<ui-text-input
|
|
label="Prefix Icon"
|
|
placeholder="Search..."
|
|
variant="outlined"
|
|
[prefixIcon]="faSearch"
|
|
[clearable]="true"
|
|
[(ngModel)]="textValues['prefix-icon']"
|
|
(inputChange)="handleInputChange('prefix-icon', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Prefix Text"
|
|
placeholder="0.00"
|
|
variant="outlined"
|
|
prefixText="$"
|
|
[(ngModel)]="textValues['prefix-text']"
|
|
(inputChange)="handleInputChange('prefix-text', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Suffix Icon"
|
|
placeholder="Enter email"
|
|
variant="outlined"
|
|
[suffixIcon]="faEnvelope"
|
|
[(ngModel)]="textValues['suffix-icon']"
|
|
(inputChange)="handleInputChange('suffix-icon', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="With Clear Button"
|
|
placeholder="Type to see clear button"
|
|
variant="outlined"
|
|
[clearable]="true"
|
|
[(ngModel)]="textValues['clearable']"
|
|
(inputChange)="handleInputChange('clearable', $event)"
|
|
(clear)="handleClear('clearable')"
|
|
/>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Special States -->
|
|
<section style="margin-bottom: 3rem;">
|
|
<h3>Special States</h3>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem;">
|
|
<ui-text-input
|
|
label="Disabled Input"
|
|
placeholder="This is disabled"
|
|
variant="outlined"
|
|
[disabled]="true"
|
|
value="Disabled value"
|
|
/>
|
|
<ui-text-input
|
|
label="Readonly Input"
|
|
placeholder="This is readonly"
|
|
variant="outlined"
|
|
[readonly]="true"
|
|
value="Readonly value"
|
|
/>
|
|
<ui-text-input
|
|
label="Loading Input"
|
|
placeholder="Loading..."
|
|
variant="outlined"
|
|
[loading]="isLoading()"
|
|
[(ngModel)]="textValues['loading']"
|
|
(inputChange)="handleInputChange('loading', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Required Input"
|
|
placeholder="This field is required"
|
|
variant="outlined"
|
|
[required]="true"
|
|
helperText="Required field"
|
|
[(ngModel)]="textValues['required']"
|
|
(inputChange)="handleInputChange('required', $event)"
|
|
/>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Character Limit -->
|
|
<section style="margin-bottom: 3rem;">
|
|
<h3>Character Limit</h3>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem;">
|
|
<ui-text-input
|
|
label="Tweet (280 chars)"
|
|
placeholder="What's happening?"
|
|
variant="outlined"
|
|
[maxLength]="280"
|
|
[showCharacterCount]="true"
|
|
[(ngModel)]="textValues['tweet']"
|
|
(inputChange)="handleInputChange('tweet', $event)"
|
|
/>
|
|
<ui-text-input
|
|
label="Short Bio (100 chars)"
|
|
placeholder="Tell us about yourself"
|
|
variant="filled"
|
|
[maxLength]="100"
|
|
[showCharacterCount]="true"
|
|
[(ngModel)]="textValues['bio']"
|
|
(inputChange)="handleInputChange('bio', $event)"
|
|
/>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Textarea Variants -->
|
|
<section style="margin-bottom: 3rem;">
|
|
<h3>Textarea Variants</h3>
|
|
|
|
<!-- Basic Textareas -->
|
|
<div style="margin-bottom: 2rem;">
|
|
<h4>Basic Textareas</h4>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 1.5rem;">
|
|
<ui-textarea
|
|
label="Small Textarea"
|
|
placeholder="Enter your message..."
|
|
size="sm"
|
|
variant="outlined"
|
|
[rows]="3"
|
|
[(ngModel)]="textValues['textarea-sm']"
|
|
(textareaChange)="handleInputChange('textarea-sm', $event)"
|
|
/>
|
|
<ui-textarea
|
|
label="Medium Textarea"
|
|
placeholder="Enter your message..."
|
|
size="md"
|
|
variant="outlined"
|
|
[rows]="4"
|
|
[(ngModel)]="textValues['textarea-md']"
|
|
(textareaChange)="handleInputChange('textarea-md', $event)"
|
|
/>
|
|
<ui-textarea
|
|
label="Large Textarea"
|
|
placeholder="Enter your message..."
|
|
size="lg"
|
|
variant="outlined"
|
|
[rows]="5"
|
|
[(ngModel)]="textValues['textarea-lg']"
|
|
(textareaChange)="handleInputChange('textarea-lg', $event)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Textarea Variants -->
|
|
<div style="margin-bottom: 2rem;">
|
|
<h4>Textarea Variants</h4>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 1.5rem;">
|
|
<ui-textarea
|
|
label="Filled Textarea"
|
|
placeholder="Enter your message..."
|
|
variant="filled"
|
|
[(ngModel)]="textValues['textarea-filled']"
|
|
(textareaChange)="handleInputChange('textarea-filled', $event)"
|
|
/>
|
|
<ui-textarea
|
|
label="Underlined Textarea"
|
|
placeholder="Enter your message..."
|
|
variant="underlined"
|
|
[(ngModel)]="textValues['textarea-underlined']"
|
|
(textareaChange)="handleInputChange('textarea-underlined', $event)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Textarea with Features -->
|
|
<div style="margin-bottom: 2rem;">
|
|
<h4>Textarea with Features</h4>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 1.5rem;">
|
|
<ui-textarea
|
|
label="Auto-resize Textarea"
|
|
placeholder="Type to see auto-resize in action..."
|
|
variant="outlined"
|
|
[autoResize]="true"
|
|
[rows]="2"
|
|
[(ngModel)]="textValues['textarea-auto']"
|
|
(textareaChange)="handleInputChange('textarea-auto', $event)"
|
|
/>
|
|
<ui-textarea
|
|
label="Character Limited"
|
|
placeholder="Maximum 500 characters..."
|
|
variant="outlined"
|
|
[maxLength]="500"
|
|
[showCharacterCount]="true"
|
|
[clearable]="true"
|
|
[(ngModel)]="textValues['textarea-limited']"
|
|
(textareaChange)="handleInputChange('textarea-limited', $event)"
|
|
(clear)="handleClear('textarea-limited')"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Textarea States -->
|
|
<div style="margin-bottom: 2rem;">
|
|
<h4>Textarea States</h4>
|
|
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 1.5rem;">
|
|
<ui-textarea
|
|
label="Error Textarea"
|
|
placeholder="This has an error..."
|
|
variant="outlined"
|
|
state="error"
|
|
errorMessage="Please provide valid feedback"
|
|
[(ngModel)]="textValues['textarea-error']"
|
|
(textareaChange)="handleInputChange('textarea-error', $event)"
|
|
/>
|
|
<ui-textarea
|
|
label="Success Textarea"
|
|
placeholder="This looks good..."
|
|
variant="outlined"
|
|
state="success"
|
|
helperText="Thank you for your feedback!"
|
|
[(ngModel)]="textValues['textarea-success']"
|
|
(textareaChange)="handleInputChange('textarea-success', $event)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Input Wrapper -->
|
|
<section style="margin-bottom: 3rem;">
|
|
<h3>Input Wrapper (Dynamic)</h3>
|
|
<div style="margin-bottom: 1rem;">
|
|
<label>
|
|
<input
|
|
type="checkbox"
|
|
[checked]="useTextarea()"
|
|
(change)="toggleInputMode()"
|
|
/>
|
|
Switch to {{ useTextarea() ? 'Text Input' : 'Textarea' }}
|
|
</label>
|
|
</div>
|
|
<div style="max-width: 500px;">
|
|
<ui-input-wrapper
|
|
[mode]="useTextarea() ? 'textarea' : 'input'"
|
|
label="Dynamic Input"
|
|
placeholder="This switches between input and textarea..."
|
|
variant="outlined"
|
|
[clearable]="true"
|
|
[prefixIcon]="faEdit"
|
|
helperText="Switch the checkbox above to change input type"
|
|
[(ngModel)]="textValues['wrapper']"
|
|
(inputChange)="handleInputChange('wrapper', $event)"
|
|
(clear)="handleClear('wrapper')"
|
|
/>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Usage Examples -->
|
|
<section style="margin-bottom: 3rem;">
|
|
<h3>Usage Examples</h3>
|
|
<div style="background: #f8f9fa; padding: 1.5rem; border-radius: 8px; border-left: 4px solid #007bff;">
|
|
<h4>Basic Text Input:</h4>
|
|
<pre style="background: #fff; padding: 1rem; border-radius: 4px; overflow-x: auto;"><code><ui-text-input
|
|
label="Email"
|
|
placeholder="Enter your email"
|
|
type="email"
|
|
variant="outlined"
|
|
size="md"
|
|
[(ngModel)]="email"
|
|
(inputChange)="handleEmailChange($event)">
|
|
</ui-text-input></code></pre>
|
|
|
|
<h4>Text Input with Icons:</h4>
|
|
<pre style="background: #fff; padding: 1rem; border-radius: 4px; overflow-x: auto;"><code><ui-text-input
|
|
label="Search"
|
|
placeholder="Search products..."
|
|
type="search"
|
|
variant="filled"
|
|
[prefixIcon]="faSearch"
|
|
[clearable]="true"
|
|
[(ngModel)]="searchTerm"
|
|
(inputChange)="handleSearch($event)">
|
|
</ui-text-input></code></pre>
|
|
|
|
<h4>Textarea:</h4>
|
|
<pre style="background: #fff; padding: 1rem; border-radius: 4px; overflow-x: auto;"><code><ui-textarea
|
|
label="Message"
|
|
placeholder="Enter your message..."
|
|
variant="outlined"
|
|
[rows]="4"
|
|
[maxLength]="500"
|
|
[showCharacterCount]="true"
|
|
[(ngModel)]="message"
|
|
(textareaChange)="handleMessageChange($event)">
|
|
</ui-textarea></code></pre>
|
|
|
|
<h4>Input Wrapper:</h4>
|
|
<pre style="background: #fff; padding: 1rem; border-radius: 4px; overflow-x: auto;"><code><ui-input-wrapper
|
|
[mode]="inputMode"
|
|
label="Dynamic Input"
|
|
placeholder="Switches between input and textarea"
|
|
variant="outlined"
|
|
[prefixIcon]="faEdit"
|
|
[(ngModel)]="content"
|
|
(inputChange)="handleContentChange($event)">
|
|
</ui-input-wrapper></code></pre>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Interactive Example -->
|
|
<section style="margin-bottom: 3rem;">
|
|
<h3>Interactive Actions</h3>
|
|
<div style="display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem;">
|
|
<button
|
|
type="button"
|
|
style="padding: 0.5rem 1rem; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer;"
|
|
(click)="toggleLoading()"
|
|
>
|
|
{{ isLoading() ? 'Stop Loading' : 'Start Loading' }}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
style="padding: 0.5rem 1rem; background: #28a745; color: white; border: none; border-radius: 4px; cursor: pointer;"
|
|
(click)="fillSampleData()"
|
|
>
|
|
Fill Sample Data
|
|
</button>
|
|
<button
|
|
type="button"
|
|
style="padding: 0.5rem 1rem; background: #dc3545; color: white; border: none; border-radius: 4px; cursor: pointer;"
|
|
(click)="clearAllInputs()"
|
|
>
|
|
Clear All
|
|
</button>
|
|
</div>
|
|
|
|
@if (lastChangedInput()) {
|
|
<div style="margin-top: 1rem; padding: 1rem; background: #e3f2fd; border-radius: 4px;">
|
|
<strong>Last changed:</strong> {{ lastChangedInput() }} = "{{ lastChangedValue() }}"
|
|
</div>
|
|
}
|
|
</section>
|
|
|
|
<!-- Values Display -->
|
|
<section style="margin-bottom: 3rem;">
|
|
<h3>Current Values</h3>
|
|
<div style="background: #f8f9fa; padding: 1rem; border-radius: 4px; max-height: 300px; overflow-y: auto;">
|
|
<pre>{{ getValuesAsJson() }}</pre>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
`,
|
|
styles: [`
|
|
h2 {
|
|
color: hsl(279, 14%, 11%);
|
|
font-size: 2rem;
|
|
margin-bottom: 2rem;
|
|
border-bottom: 2px solid hsl(258, 100%, 47%);
|
|
padding-bottom: 0.5rem;
|
|
}
|
|
|
|
h3 {
|
|
color: hsl(279, 14%, 25%);
|
|
font-size: 1.5rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
h4 {
|
|
color: hsl(287, 12%, 35%);
|
|
font-size: 1.125rem;
|
|
margin-bottom: 0.75rem;
|
|
}
|
|
|
|
section {
|
|
border: 1px solid hsl(289, 14%, 90%);
|
|
border-radius: 8px;
|
|
padding: 1.5rem;
|
|
background: hsl(286, 20%, 99%);
|
|
}
|
|
|
|
pre {
|
|
font-size: 0.875rem;
|
|
line-height: 1.5;
|
|
margin: 0.5rem 0;
|
|
}
|
|
|
|
code {
|
|
font-family: 'JetBrains Mono', monospace;
|
|
color: #d63384;
|
|
}
|
|
|
|
button {
|
|
transition: all 0.2s ease-in-out;
|
|
}
|
|
|
|
button:hover {
|
|
opacity: 0.9;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
}
|
|
`]
|
|
})
|
|
export class InputDemoComponent {
|
|
textValues: Record<string, string> = {};
|
|
lastChangedInput = signal<string>('');
|
|
lastChangedValue = signal<string>('');
|
|
isLoading = signal<boolean>(false);
|
|
useTextarea = signal<boolean>(false);
|
|
|
|
// FontAwesome icons
|
|
readonly faSearch = faSearch;
|
|
readonly faEnvelope = faEnvelope;
|
|
readonly faEdit = faEdit;
|
|
|
|
handleInputChange(inputName: string, value: string): void {
|
|
this.textValues[inputName] = value;
|
|
this.lastChangedInput.set(inputName);
|
|
this.lastChangedValue.set(value);
|
|
console.log(`Input changed: ${inputName} = "${value}"`);
|
|
}
|
|
|
|
handleClear(inputName: string): void {
|
|
this.textValues[inputName] = '';
|
|
this.lastChangedInput.set(inputName);
|
|
this.lastChangedValue.set('(cleared)');
|
|
console.log(`Input cleared: ${inputName}`);
|
|
}
|
|
|
|
toggleLoading(): void {
|
|
this.isLoading.set(!this.isLoading());
|
|
console.log(`Loading state: ${this.isLoading() ? 'started' : 'stopped'}`);
|
|
}
|
|
|
|
toggleInputMode(): void {
|
|
this.useTextarea.set(!this.useTextarea());
|
|
console.log(`Input mode: ${this.useTextarea() ? 'textarea' : 'input'}`);
|
|
}
|
|
|
|
fillSampleData(): void {
|
|
this.textValues = {
|
|
'outlined-md': 'Sample outlined text',
|
|
'email': 'user@example.com',
|
|
'search': 'sample search query',
|
|
'prefix-icon': 'search with icon',
|
|
'textarea-md': 'This is a sample message\nin a textarea component\nwith multiple lines.',
|
|
'wrapper': 'Dynamic wrapper content'
|
|
};
|
|
this.lastChangedInput.set('multiple');
|
|
this.lastChangedValue.set('(sample data filled)');
|
|
console.log('Sample data filled');
|
|
}
|
|
|
|
clearAllInputs(): void {
|
|
this.textValues = {};
|
|
this.lastChangedInput.set('all');
|
|
this.lastChangedValue.set('(cleared)');
|
|
console.log('All inputs cleared');
|
|
}
|
|
|
|
getValuesAsJson(): string {
|
|
return JSON.stringify(this.textValues, null, 2);
|
|
}
|
|
} |