Skip to content

Commit cc17fdc

Browse files
docs(textarea): Add textarea docs
1 parent 731e9b5 commit cc17fdc

6 files changed

Lines changed: 319 additions & 2 deletions

File tree

projects/docs/src/app/pages/docs/components/components.routes.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ export const routes: Routes = [
6868
path: 'input',
6969
loadComponent: () => import('./input/input').then(m => m.Input)
7070
},
71+
{
72+
path: 'textarea',
73+
loadComponent: () => import('./textarea/textarea').then(m => m.Textarea)
74+
},
7175
{
7276
path: 'table',
7377
loadComponent: () => import('./table/table').then(m => m.Table)

projects/docs/src/app/pages/docs/components/input/input.variants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export class InputWithButtonExample {
9393
<form (ngSubmit)="onSubmit()">
9494
<div class="grid items-center gap-1.5" uiFormField>
9595
<label uiLabel>Username</label>
96-
<input uiInput placeholder="slateui" [(ngModel)]="username" name="username" />
96+
<input uiInput placeholder="slateui" [(ngModel)]="username" name="username" required />
9797
<p uiDescription>This is your public display name.</p>
9898
</div>
9999
<button uiButton type="submit">Submit</button>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Component } from '@angular/core';
2+
import { ComponentPreview } from '@components/component-preview/component-preview';
3+
import { textareaVariants, textareaMeta } from './textarea.variants';
4+
5+
@Component({
6+
selector: 'docs-textarea',
7+
standalone: true,
8+
imports: [ComponentPreview],
9+
template: `
10+
<docs-component-preview
11+
[meta]="textareaMeta"
12+
[variants]="textareaVariants">
13+
</docs-component-preview>
14+
`
15+
})
16+
export class Textarea {
17+
textareaMeta = textareaMeta;
18+
textareaVariants = textareaVariants;
19+
}
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
import { Component } from '@angular/core';
2+
import { UiDescription, UiFormField, UiTextarea, UiButton, UiLabel } from 'ui';
3+
import { IVariant, IComponentMeta } from '@components/component-preview/component-preview';
4+
import { FormsModule } from '@angular/forms';
5+
6+
@Component({
7+
selector: 'textarea-default-example',
8+
template: `
9+
<textarea uiTextarea placeholder="Type your message here." [(ngModel)]="message"></textarea>
10+
`,
11+
imports: [UiTextarea, FormsModule],
12+
standalone: true,
13+
host: {
14+
'class': 'w-2/3 space-y-6 mx-auto'
15+
},
16+
})
17+
export class TextareaDefaultExample {
18+
message = '';
19+
}
20+
21+
@Component({
22+
selector: 'textarea-disabled-example',
23+
template: `
24+
<textarea uiTextarea placeholder="Type your message here." [(ngModel)]="disabledMessage" disabled></textarea>
25+
`,
26+
imports: [UiTextarea, FormsModule],
27+
standalone: true,
28+
host: {
29+
'class': 'w-2/3 space-y-6 mx-auto'
30+
},
31+
})
32+
export class TextareaDisabledExample {
33+
disabledMessage = 'This textarea is disabled';
34+
}
35+
36+
@Component({
37+
selector: 'textarea-with-label-example',
38+
template: `
39+
<div class="grid w-full gap-3" uiFormField>
40+
<label uiLabel for="message">Your message</label>
41+
<textarea uiTextarea placeholder="Type your message here." id="message" [(ngModel)]="message"></textarea>
42+
</div>
43+
`,
44+
imports: [UiTextarea, UiLabel, UiFormField, FormsModule],
45+
standalone: true,
46+
host: {
47+
'class': 'w-2/3 space-y-6 mx-auto'
48+
}
49+
})
50+
export class TextareaWithLabelExample {
51+
message = '';
52+
}
53+
54+
@Component({
55+
selector: 'textarea-with-text-example',
56+
template: `
57+
<div class="grid w-full gap-3" uiFormField>
58+
<label uiLabel for="message-2">Your Message</label>
59+
<textarea uiTextarea placeholder="Type your message here." id="message-2" [(ngModel)]="message"></textarea>
60+
<p class="text-muted-foreground text-sm">
61+
Your message will be copied to the support team.
62+
</p>
63+
</div>
64+
`,
65+
imports: [UiTextarea, UiLabel, UiFormField, FormsModule],
66+
standalone: true,
67+
host: {
68+
'class': 'w-2/3 space-y-6 mx-auto'
69+
}
70+
})
71+
export class TextareaWithTextExample {
72+
message = '';
73+
}
74+
75+
@Component({
76+
selector: 'textarea-with-button-example',
77+
template: `
78+
<div class="grid w-full gap-2">
79+
<textarea uiTextarea placeholder="Type your message here." [(ngModel)]="message"></textarea>
80+
<button uiButton>Send message</button>
81+
</div>
82+
`,
83+
imports: [UiTextarea, UiButton, FormsModule],
84+
standalone: true,
85+
host: {
86+
'class': 'w-2/3 space-y-6 mx-auto'
87+
}
88+
})
89+
export class TextareaWithButtonExample {
90+
message = '';
91+
}
92+
93+
@Component({
94+
selector: 'textarea-form-example',
95+
template: `
96+
<form (ngSubmit)="onSubmit()">
97+
<div class="grid items-center gap-1.5" uiFormField>
98+
<label uiLabel>Bio</label>
99+
<textarea name="bio" uiTextarea placeholder="Type your message here." [(ngModel)]="bio" required></textarea>
100+
<p uiDescription>
101+
Tell us a little bit about yourself
102+
</p>
103+
</div>
104+
<button uiButton type="submit">Submit</button>
105+
</form>
106+
`,
107+
imports: [UiTextarea, UiLabel, UiButton, FormsModule, UiFormField, UiDescription],
108+
standalone: true,
109+
host: {
110+
'class': 'w-2/3 space-y-6 mx-auto'
111+
},
112+
})
113+
export class TextareaFormExample {
114+
bio = '';
115+
116+
onSubmit() {
117+
console.log('Form submitted:', { bio: this.bio });
118+
}
119+
}
120+
121+
export const textareaMeta: IComponentMeta = {
122+
title: 'Textarea',
123+
description: 'A form textarea component for multi-line text input with various states and configurations.',
124+
installation: {
125+
package: 'textarea',
126+
import: `import { UiTextarea } from '@workspace/ui/directives/textarea';`,
127+
usage: `<textarea uiTextarea placeholder="Enter your message"></textarea>`
128+
},
129+
api: {
130+
props: [
131+
{ name: 'uiTextarea', type: 'Directive', description: 'Textarea directive for styling and functionality.' },
132+
{ name: 'placeholder', type: 'string', description: 'Placeholder text for the textarea.' },
133+
{ name: 'disabled', type: 'boolean', description: 'Whether the textarea is disabled.' },
134+
{ name: 'rows', type: 'number', description: 'Number of visible text lines.' },
135+
{ name: 'cols', type: 'number', description: 'Number of visible text columns.' },
136+
{ name: 'class', type: 'string', description: 'Additional CSS classes.' }
137+
]
138+
}
139+
};
140+
141+
export const textareaVariants: IVariant[] = [
142+
{
143+
title: 'Default',
144+
description: 'Basic textarea field for multi-line text input.',
145+
code: `import { UiTextarea } from '@workspace/ui/directives/textarea';
146+
import { FormsModule } from '@angular/forms';
147+
148+
@Component({
149+
selector: 'textarea-default-example',
150+
template: \`
151+
<textarea uiTextarea placeholder="Type your message here." [(ngModel)]="message"></textarea>
152+
\`,
153+
imports: [UiTextarea, FormsModule],
154+
standalone: true
155+
})
156+
export class TextareaDefaultExample {
157+
message = '';
158+
}`,
159+
component: TextareaDefaultExample
160+
},
161+
{
162+
title: 'Disabled',
163+
description: 'Disabled textarea that cannot be interacted with.',
164+
code: `import { UiTextarea } from '@workspace/ui/directives/textarea';
165+
import { FormsModule } from '@angular/forms';
166+
167+
@Component({
168+
selector: 'textarea-disabled-example',
169+
template: \`
170+
<textarea uiTextarea placeholder="Type your message here." disabled [(ngModel)]="disabledMessage"></textarea>
171+
\`,
172+
imports: [UiTextarea, FormsModule],
173+
standalone: true
174+
})
175+
export class TextareaDisabledExample {
176+
disabledMessage = 'This textarea is disabled';
177+
}`,
178+
component: TextareaDisabledExample
179+
},
180+
{
181+
title: 'With Label',
182+
description: 'Textarea field with associated label for accessibility.',
183+
code: `import { UiTextarea } from '@workspace/ui/directives/textarea';
184+
import { UiLabel } from '@workspace/ui/directives/label';
185+
import { UiFormField } from '@workspace/ui/directives/form-field';
186+
import { FormsModule } from '@angular/forms';
187+
188+
@Component({
189+
selector: 'textarea-with-label-example',
190+
template: \`
191+
<div class="grid w-full gap-3" uiFormField>
192+
<label uiLabel for="message">Your message</label>
193+
<textarea uiTextarea placeholder="Type your message here." id="message" [(ngModel)]="message"></textarea>
194+
</div>
195+
\`,
196+
imports: [UiTextarea, UiLabel, UiFormField, FormsModule],
197+
standalone: true
198+
})
199+
export class TextareaWithLabelExample {
200+
message = '';
201+
}`,
202+
component: TextareaWithLabelExample
203+
},
204+
{
205+
title: 'With Text',
206+
description: 'Textarea with descriptive text below the input.',
207+
code: `import { UiTextarea } from '@workspace/ui/directives/textarea';
208+
import { UiLabel } from '@workspace/ui/directives/label';
209+
import { UiFormField } from '@workspace/ui/directives/form-field';
210+
import { FormsModule } from '@angular/forms';
211+
212+
@Component({
213+
selector: 'textarea-with-text-example',
214+
template: \`
215+
<div class="grid w-full gap-3" uiFormField>
216+
<label uiLabel for="message-2">Your Message</label>
217+
<textarea uiTextarea placeholder="Type your message here." id="message-2" [(ngModel)]="message"></textarea>
218+
<p class="text-muted-foreground text-sm">
219+
Your message will be copied to the support team.
220+
</p>
221+
</div>
222+
\`,
223+
imports: [UiTextarea, UiLabel, UiFormField, FormsModule],
224+
standalone: true
225+
})
226+
export class TextareaWithTextExample {
227+
message = '';
228+
}`,
229+
component: TextareaWithTextExample
230+
},
231+
{
232+
title: 'With Button',
233+
description: 'Textarea field with a submit button.',
234+
code: `import { UiTextarea } from '@workspace/ui/directives/textarea';
235+
import { UiButton } from '@workspace/ui/directives/button';
236+
import { FormsModule } from '@angular/forms';
237+
238+
@Component({
239+
selector: 'textarea-with-button-example',
240+
template: \`
241+
<div class="grid w-full gap-2">
242+
<textarea uiTextarea placeholder="Type your message here." [(ngModel)]="message"></textarea>
243+
<button uiButton>Send message</button>
244+
</div>
245+
\`,
246+
imports: [UiTextarea, UiButton, FormsModule],
247+
standalone: true
248+
})
249+
export class TextareaWithButtonExample {
250+
message = '';
251+
}`,
252+
component: TextareaWithButtonExample
253+
},
254+
{
255+
title: 'Form',
256+
description: 'Complete form with textarea using ngModel and form field directives.',
257+
code: `import { UiTextarea } from '@workspace/ui/directives/textarea';
258+
import { UiButton } from '@workspace/ui/directives/button';
259+
import { UiFormField, UiDescription, UiLabel } from '@workspace/ui/directives/form-field';
260+
import { FormsModule } from '@angular/forms';
261+
262+
@Component({
263+
selector: 'textarea-form-example',
264+
template: \`
265+
<form (ngSubmit)="onSubmit()">
266+
<div class="grid items-center gap-1.5" uiFormField>
267+
<label uiLabel>Bio</label>
268+
<textarea
269+
uiTextarea
270+
placeholder="Tell us a little bit about yourself"
271+
[(ngModel)]="bio"
272+
name="bio" required>
273+
</textarea>
274+
<p uiDescription>
275+
You can <span>@mention</span> other users and organizations.
276+
</p>
277+
</div>
278+
<button uiButton type="submit">Submit</button>
279+
</form>
280+
\`,
281+
imports: [UiTextarea, UiLabel, UiButton, UiFormField, UiDescription, FormsModule],
282+
standalone: true
283+
})
284+
export class TextareaFormExample {
285+
bio = '';
286+
287+
onSubmit() {
288+
console.log('Form submitted:', { bio: this.bio });
289+
}
290+
}`,
291+
component: TextareaFormExample
292+
}
293+
];

projects/docs/src/app/shared/components/sidebar/sidebar.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export class Sidebar {
5757
{ name: 'Dropdown Menu', path: 'dropdown-menu' },
5858
{ name: 'Label', path: 'label' },
5959
{ name: 'Input', path: 'input' },
60+
{ name: 'Textarea', path: 'textarea' },
6061
{ name: 'Popover', path: 'popover' },
6162
{ name: 'Progress', path: 'progress' },
6263
// { name: 'Select', path: 'select' },

projects/ui/src/directives/input.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { NgpInput } from "ng-primitives/input";
55
const inputVariants = tv({
66
base: ["file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 md:text-sm",
77
"data-[focus]:border-ring data-[focus]:ring-ring/50 data-[focus]:ring-[3px]",
8-
"aria-invalid:ring-destructive/20 [&.ng-invalid.ng-touched]:ring-destructive/20 [&.ng-invalid.ng-touched]:border-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"].join(' ')
8+
"aria-invalid:ring-destructive/20 [&[data-touched][data-invalid]]:ring-destructive/20 [&[data-touched][data-invalid]]:border-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"].join(' ')
99
});
1010

1111
@Directive({

0 commit comments

Comments
 (0)