@kern-ux-annex/kern-angular-kit 0.3.6 → 1.0.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/INTELLISENSE.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  This package provides comprehensive IntelliSense support for all KERN Angular Kit components to enhance your development experience with autocomplete, type checking, and inline documentation.
4
4
 
5
+ **Component Coverage**: This documentation covers 30+ components including layout components, form inputs, data display components, and typography elements.
6
+
5
7
  ## Features
6
8
 
7
9
  ### 🎯 TypeScript Component Interfaces
@@ -12,7 +14,13 @@ All components have strongly typed interfaces that provide autocomplete and comp
12
14
  import {
13
15
  KernAccordionInputs,
14
16
  KernAlertInputs,
17
+ KernBadgeInputs,
18
+ KernButtonInputs,
19
+ KernCardInputs,
15
20
  KernDialogInputs,
21
+ KernTableInputs,
22
+ KernSummaryInputs,
23
+ KernProgressInputs,
16
24
  ComponentInputs
17
25
  } from '@kern-ux-annex/kern-angular-kit';
18
26
 
@@ -22,11 +30,34 @@ const accordionConfig: KernAccordionInputs = {
22
30
  open: true // TypeScript validates this boolean
23
31
  };
24
32
 
33
+ // Card configuration with multiple properties
34
+ const cardConfig: KernCardInputs = {
35
+ title: 'Feature Card',
36
+ size: 'large',
37
+ btnPrimaryLabelText: 'Learn More',
38
+ btnSecondaryLabelText: 'Skip'
39
+ };
40
+
25
41
  // Generic component configuration helper
26
42
  const alertConfig: ComponentInputs<'kern-alert'> = {
27
43
  title: 'Warning!',
28
44
  type: 'warning' // IntelliSense shows available types
29
45
  };
46
+
47
+ // Table configuration with typed data
48
+ const tableConfig: KernTableInputs = {
49
+ caption: 'Data Overview',
50
+ columns: [
51
+ { key: 'name', header: 'Name' },
52
+ { key: 'value', header: 'Value', numeric: true }
53
+ ],
54
+ data: [
55
+ { name: 'Item 1', value: 100 },
56
+ { name: 'Item 2', value: 200 }
57
+ ],
58
+ striped: true,
59
+ responsive: true
60
+ };
30
61
  ```
31
62
 
32
63
  ### 📋 JSON Schema Validation
@@ -60,6 +91,40 @@ Components provide full IntelliSense in Angular templates with property validati
60
91
  <p>Accordion content goes here</p>
61
92
  </kern-accordion>
62
93
 
94
+ <!-- Button with icon and event handling -->
95
+ <kern-button
96
+ variant="primary"
97
+ iconLeft="arrow-right"
98
+ [disabled]="isLoading"
99
+ (clickEvent)="onSubmit($event)"
100
+ >
101
+ Submit Form
102
+ </kern-button>
103
+
104
+ <!-- Card component with multiple features -->
105
+ <kern-card
106
+ [title]="cardTitle"
107
+ [preline]="cardPreline"
108
+ [subline]="cardSubline"
109
+ size="large"
110
+ [btnPrimaryLabelText]="primaryButtonText"
111
+ [btnSecondaryLabelText]="secondaryButtonText"
112
+ (btnPrimaryClickEvent)="onPrimaryAction($event)"
113
+ (btnSecondaryClickEvent)="onSecondaryAction($event)"
114
+ >
115
+ <p>Card content</p>
116
+ </kern-card>
117
+
118
+ <!-- Data table with configuration -->
119
+ <kern-table
120
+ [columns]="tableColumns"
121
+ [data]="tableData"
122
+ [striped]="true"
123
+ [responsive]="true"
124
+ caption="User Data Overview"
125
+ >
126
+ </kern-table>
127
+
63
128
  <!-- Type checking and validation for form inputs -->
64
129
  <kern-input-text
65
130
  labelText="Username"
@@ -69,6 +134,25 @@ Components provide full IntelliSense in Angular templates with property validati
69
134
  >
70
135
  </kern-input-text>
71
136
 
137
+ <!-- Number input with constraints -->
138
+ <kern-input-number
139
+ labelText="Age"
140
+ [required]="true"
141
+ [min]="18"
142
+ [max]="120"
143
+ step="1"
144
+ >
145
+ </kern-input-number>
146
+
147
+ <!-- Summary component with action link -->
148
+ <kern-summary
149
+ [title]="summaryTitle"
150
+ [items]="summaryItems"
151
+ [actionLinkHref]="detailsUrl"
152
+ (actionLinkClickEvent)="onViewDetails($event)"
153
+ >
154
+ </kern-summary>
155
+
72
156
  <!-- Dialog with event handlers -->
73
157
  <kern-dialog
74
158
  [title]="dialogTitle"
@@ -79,6 +163,17 @@ Components provide full IntelliSense in Angular templates with property validati
79
163
  >
80
164
  <p>Dialog content</p>
81
165
  </kern-dialog>
166
+
167
+ <!-- Progress indicator -->
168
+ <kern-progress
169
+ [value]="currentProgress"
170
+ [max]="totalSteps"
171
+ label="Upload Progress"
172
+ >
173
+ </kern-progress>
174
+
175
+ <!-- Badge with icon -->
176
+ <kern-badge variant="success" icon="check-circle"> Completed </kern-badge>
82
177
  ```
83
178
 
84
179
  ### 🌐 Custom Element Support
@@ -91,9 +186,36 @@ import '@kern-ux-annex/kern-angular-kit';
91
186
 
92
187
  // Now you have full IntelliSense in JSX
93
188
  const MyComponent = () => (
94
- <kern-accordion title="My Accordion" open={false}>
95
- <p>Content</p>
96
- </kern-accordion>
189
+ <div>
190
+ <kern-accordion title="My Accordion" open={false}>
191
+ <p>Content</p>
192
+ </kern-accordion>
193
+
194
+ <kern-button
195
+ variant="primary"
196
+ iconLeft="arrow-right"
197
+ onClick={handleClick}>
198
+ Click me
199
+ </kern-button>
200
+
201
+ <kern-card
202
+ title="Feature Card"
203
+ preline="New"
204
+ size="large"
205
+ btnPrimaryLabelText="Learn More">
206
+ <p>Card content</p>
207
+ </kern-card>
208
+
209
+ <kern-table
210
+ columns={tableColumns}
211
+ data={tableData}
212
+ striped={true}
213
+ responsive={true} />
214
+
215
+ <kern-badge variant="success" icon="check">
216
+ Completed
217
+ </kern-badge>
218
+ </div>
97
219
  );
98
220
  ```
99
221
 
@@ -105,14 +227,33 @@ Helper functions for working with KERN components programmatically:
105
227
  import {
106
228
  isKernAccordion,
107
229
  isKernDialog,
108
- KernDialogElement
230
+ isKernButton,
231
+ isKernCard,
232
+ isKernTable,
233
+ KernDialogElement,
234
+ KernButtonElement,
235
+ KernCardElement
109
236
  } from '@kern-ux-annex/kern-angular-kit';
110
237
 
111
- // Type-safe DOM manipulation
112
- const element = document.querySelector('kern-dialog');
113
- if (isKernDialog(element)) {
114
- element.showModal(); // TypeScript knows this method exists
115
- element.title = 'New Title'; // Property is typed
238
+ // Type-safe DOM manipulation for dialogs
239
+ const dialogElement = document.querySelector('kern-dialog');
240
+ if (isKernDialog(dialogElement)) {
241
+ dialogElement.showModal(); // TypeScript knows this method exists
242
+ dialogElement.title = 'New Title'; // Property is typed
243
+ }
244
+
245
+ // Type-safe button interactions
246
+ const buttonElement = document.querySelector('kern-button');
247
+ if (isKernButton(buttonElement)) {
248
+ buttonElement.disabled = true; // TypeScript validates property
249
+ buttonElement.variant = 'secondary'; // IntelliSense shows available variants
250
+ }
251
+
252
+ // Type-safe card manipulation
253
+ const cardElement = document.querySelector('kern-card');
254
+ if (isKernCard(cardElement)) {
255
+ cardElement.title = 'Updated Title';
256
+ cardElement.size = 'large'; // TypeScript validates size options
116
257
  }
117
258
  ```
118
259
 
@@ -169,7 +310,7 @@ export class AppModule {}
169
310
 
170
311
  ## Component Reference
171
312
 
172
- ### 📦 Layout Components
313
+ ### 📦 Layout & UI Components
173
314
 
174
315
  #### kern-accordion
175
316
 
@@ -180,6 +321,14 @@ interface KernAccordionInputs {
180
321
  }
181
322
  ```
182
323
 
324
+ #### kern-accordion-group
325
+
326
+ ```typescript
327
+ interface KernAccordionGroupInputs {
328
+ // Container for multiple accordion items with consistent styling
329
+ }
330
+ ```
331
+
183
332
  #### kern-alert
184
333
 
185
334
  ```typescript
@@ -189,6 +338,59 @@ interface KernAlertInputs {
189
338
  }
190
339
  ```
191
340
 
341
+ #### kern-badge
342
+
343
+ ```typescript
344
+ interface KernBadgeInputs {
345
+ variant?: 'info' | 'success' | 'warning' | 'danger'; // Optional: Badge style (default: 'info')
346
+ icon?: string | null; // Optional: Icon name to display
347
+ }
348
+ ```
349
+
350
+ #### kern-button
351
+
352
+ ```typescript
353
+ interface KernButtonInputs {
354
+ variant?: 'primary' | 'secondary' | 'tertiary'; // Optional: Button style (default: 'primary')
355
+ block?: boolean; // Optional: Full-width button (default: false)
356
+ disabled?: boolean; // Optional: Disabled state (default: false)
357
+ type?: 'button' | 'submit' | 'reset'; // Optional: Button type (default: 'button')
358
+ iconLeft?: string | null; // Optional: Left icon name
359
+ iconRight?: string | null; // Optional: Right icon name
360
+ srOnlyLabel?: boolean; // Optional: Screen reader only label (default: false)
361
+ }
362
+
363
+ // Events emitted by kern-button
364
+ interface KernButtonOutputs {
365
+ clickEvent: Event; // Fired when button is clicked
366
+ }
367
+ ```
368
+
369
+ #### kern-card
370
+
371
+ ```typescript
372
+ interface KernCardInputs {
373
+ title?: string | null; // Optional: Card title
374
+ titleLinkHref?: string | null; // Optional: Title link URL
375
+ titleLinkTarget?: '_self' | '_blank' | '_parent' | '_top'; // Optional: Link target (default: '_self')
376
+ preline?: string | null; // Optional: Text above title
377
+ subline?: string | null; // Optional: Text below title
378
+ imgSrc?: string | null; // Optional: Image source URL
379
+ imgAlt?: string | null; // Optional: Image alt text
380
+ size?: 'default' | 'small' | 'large'; // Optional: Card size (default: 'default')
381
+ headingLevel?: '1' | '2' | '3' | '4' | '5'; // Optional: Heading level (default: '2')
382
+ btnPrimaryLabelText?: string | null; // Optional: Primary button text
383
+ btnSecondaryLabelText?: string | null; // Optional: Secondary button text
384
+ }
385
+
386
+ // Events emitted by kern-card
387
+ interface KernCardOutputs {
388
+ titleLinkClickEvent: Event; // Fired when title link is clicked
389
+ btnPrimaryClickEvent: Event; // Fired when primary button is clicked
390
+ btnSecondaryClickEvent: Event; // Fired when secondary button is clicked
391
+ }
392
+ ```
393
+
192
394
  #### kern-dialog
193
395
 
194
396
  ```typescript
@@ -208,6 +410,33 @@ interface KernDialogOutputs {
208
410
  }
209
411
  ```
210
412
 
413
+ #### kern-divider
414
+
415
+ ```typescript
416
+ interface KernDividerInputs {
417
+ // Simple horizontal divider with consistent styling
418
+ }
419
+ ```
420
+
421
+ #### kern-icon
422
+
423
+ ```typescript
424
+ interface KernIconInputs {
425
+ name: string; // Required: Icon name/identifier
426
+ size?: string; // Optional: Icon size
427
+ }
428
+ ```
429
+
430
+ #### kern-link
431
+
432
+ ```typescript
433
+ interface KernLinkInputs {
434
+ href: string; // Required: Link URL
435
+ target?: '_self' | '_blank' | '_parent' | '_top'; // Optional: Link target (default: '_self')
436
+ external?: boolean; // Optional: External link indicator (default: false)
437
+ }
438
+ ```
439
+
211
440
  #### kern-loader
212
441
 
213
442
  ```typescript
@@ -216,6 +445,95 @@ interface KernLoaderInputs {
216
445
  }
217
446
  ```
218
447
 
448
+ #### kern-progress
449
+
450
+ ```typescript
451
+ interface KernProgressInputs {
452
+ value: number; // Required: Current progress value
453
+ max?: number; // Optional: Maximum value (default: 100)
454
+ label?: string; // Optional: Progress label
455
+ }
456
+ ```
457
+
458
+ ### � Data Display Components
459
+
460
+ #### kern-table
461
+
462
+ ```typescript
463
+ interface KernTableInputs {
464
+ responsive?: boolean; // Optional: Responsive table (default: true)
465
+ small?: boolean; // Optional: Compact table (default: false)
466
+ striped?: boolean; // Optional: Striped rows (default: false)
467
+ caption?: string | null; // Optional: Table caption
468
+ columns: KernTableColumn[]; // Required: Column definitions
469
+ data: KernTableRow[]; // Required: Table data
470
+ footer?: KernTableRow[] | null; // Optional: Footer rows
471
+ rowHeaderKey?: string | null; // Optional: Key for row headers
472
+ }
473
+
474
+ interface KernTableColumn {
475
+ key: string; // Column data key
476
+ header: string; // Column header text
477
+ numeric?: boolean; // Optional: Numeric column (default: false)
478
+ }
479
+
480
+ type KernTableRow = Record<string, unknown>; // Row data object
481
+ ```
482
+
483
+ #### kern-summary
484
+
485
+ ```typescript
486
+ interface KernSummaryInputs {
487
+ titleId?: string; // Optional: Custom title ID
488
+ title?: string | null; // Optional: Summary title
489
+ titleNumber?: string | null; // Optional: Title number/prefix
490
+ headingLevel?: '1' | '2' | '3' | '4' | '5' | '6'; // Optional: Heading level (default: '3')
491
+ items: { term: string; description: string }[]; // Required: Summary items
492
+ actionLinkHref?: string | null; // Optional: Action link URL
493
+ actionLinkTarget?: '_self' | '_blank' | '_parent' | '_top'; // Optional: Link target (default: '_self')
494
+ }
495
+
496
+ // Events emitted by kern-summary
497
+ interface KernSummaryOutputs {
498
+ actionLinkClickEvent: Event; // Fired when action link is clicked
499
+ }
500
+ ```
501
+
502
+ #### kern-summary-group
503
+
504
+ ```typescript
505
+ interface KernSummaryGroupInputs {
506
+ // Container for multiple summary components with consistent styling
507
+ }
508
+ ```
509
+
510
+ #### kern-description-list
511
+
512
+ ```typescript
513
+ interface KernDescriptionListInputs {
514
+ items: { term: string; description: string }[]; // Required: List items
515
+ orientation?: 'horizontal' | 'vertical'; // Optional: List orientation
516
+ }
517
+ ```
518
+
519
+ #### kern-tasklist
520
+
521
+ ```typescript
522
+ interface KernTasklistInputs {
523
+ tasks: KernTasklistItem[]; // Required: Task items
524
+ editable?: boolean; // Optional: Allow editing tasks (default: false)
525
+ }
526
+
527
+ interface KernTasklistItem {
528
+ id: string; // Unique task identifier
529
+ text: string; // Task description
530
+ completed?: boolean; // Task completion status
531
+ href?: string; // Optional task link
532
+ }
533
+ ```
534
+
535
+ ### �📝 Form Components
536
+
219
537
  ### 📝 Form Components
220
538
 
221
539
  All form components extend the base input interface:
@@ -230,14 +548,56 @@ interface KernInputBaseInputs {
230
548
  }
231
549
  ```
232
550
 
233
- #### Specialized Form Components
551
+ #### kern-fieldset
552
+
553
+ ```typescript
554
+ interface KernFieldsetInputs {
555
+ legend: string; // Required: Fieldset legend
556
+ required?: boolean; // Optional: Mark as required
557
+ }
558
+ ```
559
+
560
+ #### kern-input-error
561
+
562
+ ```typescript
563
+ interface KernInputErrorInputs {
564
+ errorText: string; // Required: Error message text
565
+ }
566
+ ```
567
+
568
+ #### kern-input-hint
569
+
570
+ ```typescript
571
+ interface KernInputHintInputs {
572
+ hintText: string; // Required: Hint message text
573
+ }
574
+ ```
575
+
576
+ #### Specialized Form Input Components
234
577
 
235
- - **kern-input-text**: Adds `inputmode` and `maxlength` properties
578
+ - **kern-input-text**: Adds `inputmode` ('decimal' | 'numeric' | null) and `maxlength` properties
579
+ - **kern-input-number**: Adds `min`, `max`, `step`, `autocomplete`, `placeholder` properties
236
580
  - **kern-input-date**: Adds `min` and `max` date constraints
237
- - **kern-input-file**: Adds `accept` and `multiple` properties
238
- - **kern-input-radio**: Adds required `value` and `name` properties
239
- - **kern-input-select**: Adds `multiple` property
240
- - **kern-input-textarea**: Adds `rows`, `cols`, and `maxlength` properties
581
+ - **kern-input-email**: Standard email input with validation
582
+ - **kern-input-password**: Adds `maxlength` property for password constraints
583
+ - **kern-input-tel**: Telephone number input with appropriate input mode
584
+ - **kern-input-url**: URL input with validation
585
+ - **kern-input-file**: Adds `accept` and `multiple` properties for file selection
586
+ - **kern-input-radio**: Adds required `value` and `name` properties for radio groups
587
+ - **kern-input-select**: Adds `multiple` property for multi-selection
588
+ - **kern-input-checkbox**: Standard checkbox input
589
+ - **kern-input-textarea**: Adds `rows`, `cols`, and `maxlength` properties for text areas
590
+
591
+ ### 🎨 Typography Components
592
+
593
+ #### kern-heading
594
+
595
+ ```typescript
596
+ interface KernHeadingInputs {
597
+ level?: '1' | '2' | '3' | '4' | '5' | '6'; // Optional: Heading level (default: '1')
598
+ text: string; // Required: Heading text content
599
+ }
600
+ ```
241
601
 
242
602
  ## Usage Examples
243
603
 
@@ -245,20 +605,142 @@ interface KernInputBaseInputs {
245
605
 
246
606
  ```typescript
247
607
  import { Component } from '@angular/core';
248
- import { KernAccordionInputs } from '@kern-ux-annex/kern-angular-kit';
608
+ import {
609
+ KernAccordionInputs,
610
+ KernCardInputs,
611
+ KernButtonInputs
612
+ } from '@kern-ux-annex/kern-angular-kit';
249
613
 
250
614
  @Component({
251
615
  template: `
252
- <kern-accordion [title]="config.title" [open]="config.open">
616
+ <!-- Accordion with configuration -->
617
+ <kern-accordion
618
+ [title]="accordionConfig.title"
619
+ [open]="accordionConfig.open"
620
+ >
253
621
  <p>Dynamic content based on configuration</p>
254
622
  </kern-accordion>
623
+
624
+ <!-- Card with buttons and events -->
625
+ <kern-card
626
+ [title]="cardConfig.title"
627
+ [preline]="cardConfig.preline"
628
+ [subline]="cardConfig.subline"
629
+ [btnPrimaryLabelText]="cardConfig.btnPrimaryLabelText"
630
+ [btnSecondaryLabelText]="cardConfig.btnSecondaryLabelText"
631
+ (btnPrimaryClickEvent)="onCardPrimaryAction($event)"
632
+ (btnSecondaryClickEvent)="onCardSecondaryAction($event)"
633
+ >
634
+ <p>Card content goes here</p>
635
+ </kern-card>
636
+
637
+ <!-- Button with icon and events -->
638
+ <kern-button
639
+ [variant]="buttonConfig.variant"
640
+ [iconLeft]="buttonConfig.iconLeft"
641
+ [disabled]="buttonConfig.disabled"
642
+ (clickEvent)="onButtonClick($event)"
643
+ >
644
+ Click me
645
+ </kern-button>
255
646
  `
256
647
  })
257
648
  export class MyComponent {
258
- config: KernAccordionInputs = {
649
+ accordionConfig: KernAccordionInputs = {
259
650
  title: 'Configuration Panel',
260
651
  open: false
261
652
  };
653
+
654
+ cardConfig: KernCardInputs = {
655
+ title: 'Feature Card',
656
+ preline: 'New Feature',
657
+ subline: 'Available now',
658
+ btnPrimaryLabelText: 'Learn More',
659
+ btnSecondaryLabelText: 'Skip'
660
+ };
661
+
662
+ buttonConfig: KernButtonInputs = {
663
+ variant: 'primary',
664
+ iconLeft: 'arrow-right',
665
+ disabled: false
666
+ };
667
+
668
+ onCardPrimaryAction(event: Event) {
669
+ console.log('Primary action clicked', event);
670
+ }
671
+
672
+ onCardSecondaryAction(event: Event) {
673
+ console.log('Secondary action clicked', event);
674
+ }
675
+
676
+ onButtonClick(event: Event) {
677
+ console.log('Button clicked', event);
678
+ }
679
+ }
680
+ ```
681
+
682
+ ### 📊 Data Display Examples
683
+
684
+ ```typescript
685
+ import { Component } from '@angular/core';
686
+ import {
687
+ KernTableInputs,
688
+ KernTableColumn,
689
+ KernTableRow,
690
+ KernSummaryInputs
691
+ } from '@kern-ux-annex/kern-angular-kit';
692
+
693
+ @Component({
694
+ template: `
695
+ <!-- Data table with configuration -->
696
+ <kern-table
697
+ [columns]="tableConfig.columns"
698
+ [data]="tableConfig.data"
699
+ [striped]="tableConfig.striped"
700
+ [responsive]="tableConfig.responsive"
701
+ [caption]="tableConfig.caption"
702
+ >
703
+ </kern-table>
704
+
705
+ <!-- Summary component -->
706
+ <kern-summary
707
+ [title]="summaryConfig.title"
708
+ [items]="summaryConfig.items"
709
+ [actionLinkHref]="summaryConfig.actionLinkHref"
710
+ (actionLinkClickEvent)="onSummaryAction($event)"
711
+ >
712
+ </kern-summary>
713
+ `
714
+ })
715
+ export class DataDisplayComponent {
716
+ tableConfig: KernTableInputs = {
717
+ caption: 'User Statistics',
718
+ striped: true,
719
+ responsive: true,
720
+ columns: [
721
+ { key: 'name', header: 'Name' },
722
+ { key: 'age', header: 'Age', numeric: true },
723
+ { key: 'email', header: 'Email' }
724
+ ],
725
+ data: [
726
+ { name: 'John Doe', age: 30, email: 'john@example.com' },
727
+ { name: 'Jane Smith', age: 25, email: 'jane@example.com' }
728
+ ]
729
+ };
730
+
731
+ summaryConfig: KernSummaryInputs = {
732
+ title: 'Project Summary',
733
+ actionLinkHref: '/project/details',
734
+ items: [
735
+ { term: 'Status', description: 'In Progress' },
736
+ { term: 'Due Date', description: '2024-12-31' },
737
+ { term: 'Team Size', description: '5 members' }
738
+ ]
739
+ };
740
+
741
+ onSummaryAction(event: Event) {
742
+ console.log('Summary action clicked', event);
743
+ }
262
744
  }
263
745
  ```
264
746
 
@@ -267,7 +749,8 @@ export class MyComponent {
267
749
  ```typescript
268
750
  import {
269
751
  ComponentInputs,
270
- KernComponentSelector
752
+ KernComponentSelector,
753
+ KernInputBaseInputs
271
754
  } from '@kern-ux-annex/kern-angular-kit';
272
755
 
273
756
  interface FormField {
@@ -278,11 +761,19 @@ interface FormField {
278
761
  const formFields: FormField[] = [
279
762
  {
280
763
  component: 'kern-input-text',
281
- config: { labelText: 'Name', required: true }
764
+ config: { labelText: 'Full Name', required: true, maxlength: 100 }
282
765
  },
283
766
  {
284
767
  component: 'kern-input-email',
285
- config: { labelText: 'Email', required: true }
768
+ config: { labelText: 'Email Address', required: true }
769
+ },
770
+ {
771
+ component: 'kern-input-number',
772
+ config: { labelText: 'Age', min: 18, max: 120, optional: false }
773
+ },
774
+ {
775
+ component: 'kern-input-textarea',
776
+ config: { labelText: 'Comments', rows: 4, maxlength: 500, optional: true }
286
777
  }
287
778
  ];
288
779
  ```