@vsn-ux/ngx-gaia 0.9.13 → 0.9.15

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/DOCS.md CHANGED
@@ -158,6 +158,100 @@ Selectable card
158
158
  </ga-card>
159
159
  ```
160
160
 
161
+ ## Chip
162
+
163
+ Chip components for selectable options in a compact, pill-shaped format.
164
+
165
+ **Angular module: GaChipModule**
166
+
167
+ ### `<ga-chip-listbox>`
168
+
169
+ Container component for managing chip selection and keyboard navigation.
170
+
171
+ #### Inputs:
172
+
173
+ - `value: any | any[]` - Selected value (single value or array for multiple selection)
174
+ - `multiple: boolean` - Enable multiple selection
175
+ - `disabled: boolean` - Disable entire listbox
176
+ - `compareWith: (a: any, b: any) => boolean` - Custom value comparison function
177
+ - `orientation: 'horizontal' | 'vertical'` - Keyboard navigation orientation (default: 'horizontal')
178
+ - `variant: 'default' | 'transparent'` - Visual variant (default: 'default')
179
+
180
+ #### Outputs:
181
+
182
+ - `valueChange(value: any | any[])` - Emitted when selection changes
183
+
184
+ #### Methods:
185
+
186
+ - `focus(): void` - Focus the listbox
187
+
188
+ ### `<ga-chip>`
189
+
190
+ Individual chip component for selectable options.
191
+
192
+ #### Inputs:
193
+
194
+ - `value: any` - Chip value (required)
195
+ - `disabled: boolean` - Disable individual chip (default: false)
196
+
197
+ #### Properties:
198
+
199
+ - `selected: Signal<boolean | null>` - Read-only signal indicating if chip is selected
200
+
201
+ ### Examples:
202
+
203
+ Single selection
204
+
205
+ ```html
206
+ <ga-chip-listbox [(value)]="selectedValue">
207
+ <ga-chip value="Apple">Apple</ga-chip>
208
+ <ga-chip value="Banana">Banana</ga-chip>
209
+ <ga-chip value="Orange">Orange</ga-chip>
210
+ </ga-chip-listbox>
211
+ ```
212
+
213
+ Multiple selection
214
+
215
+ ```html
216
+ <ga-chip-listbox [(value)]="selectedValues" multiple>
217
+ <ga-chip value="Apple">Apple</ga-chip>
218
+ <ga-chip value="Banana">Banana</ga-chip>
219
+ <ga-chip value="Orange" disabled>Orange</ga-chip>
220
+ </ga-chip-listbox>
221
+ ```
222
+
223
+ With icons
224
+
225
+ ```html
226
+ <ga-chip-listbox [(value)]="selected" multiple>
227
+ <ga-chip value="Apple">
228
+ <ga-icon [icon]="icons.Apple" size="16" />
229
+ Apple
230
+ </ga-chip>
231
+ <ga-chip #chip value="Grape">
232
+ <ga-icon [icon]="icons.Grape" size="16" />
233
+ Grape @if(chip.selected()){
234
+ <ga-icon [icon]="icons.CircleX" size="24" />
235
+ }
236
+ </ga-chip>
237
+ </ga-chip-listbox>
238
+ ```
239
+
240
+ Custom value comparison
241
+
242
+ ```typescript
243
+ compareUsers(user1: User, user2: User): boolean {
244
+ return user1.id === user2.id;
245
+ }
246
+ ```
247
+
248
+ ```html
249
+ <ga-chip-listbox [value]="selectedUser" [compareWith]="compareUsers">
250
+ <ga-chip [value]="user1">{{ user1.name }}</ga-chip>
251
+ <ga-chip [value]="user2">{{ user2.name }}</ga-chip>
252
+ </ga-chip-listbox>
253
+ ```
254
+
161
255
  ## Checkbox
162
256
 
163
257
  Checkbox component for boolean selections.
@@ -286,6 +380,333 @@ Abstract service for converting between external and internal date representatio
286
380
  <ga-datepicker #picker></ga-datepicker>
287
381
  ```
288
382
 
383
+ ## Data Select
384
+
385
+ Data-driven select component that works with arrays of items and provides advanced features like search, multi-select, grouping, and custom templates.
386
+
387
+ **Angular module: GaDataSelectModule**
388
+
389
+ ### `<ga-data-select>`
390
+
391
+ Data select component that automatically generates options from an items array.
392
+
393
+ #### Inputs:
394
+
395
+ - `items: IGaSelectOption[]` - Array of items to display as options (default: [])
396
+ - `value: any | any[] | null` - Selected value (default: null)
397
+ - `placeholder: string` - Placeholder text (default: '')
398
+ - `multiple: boolean` - Enable multi-select mode (default: false)
399
+ - `disabled: boolean` - Disabled state (default: false)
400
+ - `invalid: boolean | null` - Invalid state styling (default: null)
401
+ - `compareFn: (o1: any, o2: any) => boolean` - Comparison function for object values (default: (a, b) => a === b)
402
+ - `searchable: boolean` - Enable search/filter functionality (default: false)
403
+ - `customFilter: boolean` - Disable built-in filtering for custom implementation (default: false)
404
+ - `clearable: boolean` - Show clear button (default: false)
405
+ - `clearableLabel: string` - Custom label for clear button
406
+ - `noOptionsLabel: string` - Custom message when no options available
407
+ - `canSelectNullable: boolean` - Allow selection of null/undefined/empty values (default: false)
408
+ - `leftIcon: GaIconData` - Icon to display on the left
409
+ - `id: string | null` - Element ID (default: auto-generated)
410
+ - `bindValue: string` - Property path to use as option value
411
+ - `bindLabel: string` - Property path to use as option label
412
+ - `groupBy: string | ((item: IGaSelectOption) => string)` - Property or function for grouping options
413
+ - `loading: boolean` - Show loading spinner (default: false)
414
+ - `withOptionInput: boolean | null` - Show radio/checkbox in options (default: null)
415
+
416
+ #### Outputs:
417
+
418
+ - `valueChange(value: any | any[] | null)` - Emitted when value changes
419
+ - `searchValueChange(value: string | null)` - Emitted when search text changes
420
+ - `opened()` - Emitted when dropdown opens
421
+ - `closed()` - Emitted when dropdown closes
422
+ - `optionsEndReached()` - Emitted when user scrolls to bottom of options
423
+
424
+ ### `IGaSelectOption<T>`
425
+
426
+ Type for option items with special properties:
427
+
428
+ - `$disabled?: boolean` - Marks option as disabled
429
+ - `$typeaheadLabel?: string` - Custom label for search/typeahead functionality
430
+
431
+ ### `[gaDataSelectValueTpl]`
432
+
433
+ Directive for customizing the selected value display.
434
+
435
+ #### Template Context:
436
+
437
+ - `$implicit` - The label of the selected item
438
+ - `value` - The value of the selected item
439
+ - `item` - The full item object
440
+
441
+ ### `[gaDataSelectOptionTpl]`
442
+
443
+ Directive for customizing option labels in dropdown.
444
+
445
+ #### Template Context:
446
+
447
+ - `$implicit` - The label of the option
448
+ - `value` - The value of the option
449
+ - `item` - The full item object
450
+
451
+ ### `[gaDataSelectOptgroupLabelTpl]`
452
+
453
+ Directive for customizing optgroup labels.
454
+
455
+ #### Template Context:
456
+
457
+ - `$implicit` - The label of the optgroup
458
+ - `label` - The label of the optgroup
459
+ - `items` - Array of items in the group
460
+
461
+ ### GaDataSelectI18n
462
+
463
+ Service for data-select internationalization.
464
+
465
+ #### Properties:
466
+
467
+ - `clearLabel: string` - Label for clear button (default: 'Clear')
468
+ - `searchInputLabel: string` - Accessible label for search input (default: 'Search')
469
+ - `noOptionsLabel: string` - Message when no options available (default: 'No options')
470
+
471
+ ### GaDataSelectRequiredValidator
472
+
473
+ Built-in required validator for Angular Forms integration.
474
+
475
+ ### Providers:
476
+
477
+ - `provideGaDataSelectI18n(value: GaDataSelectI18n | (() => GaDataSelectI18n))` - Configure data-select i18n labels
478
+
479
+ ### Examples:
480
+
481
+ Basic usage with bindValue and bindLabel
482
+
483
+ ```html
484
+ <ga-data-select
485
+ placeholder="Select an option"
486
+ [items]="options"
487
+ bindValue="id"
488
+ bindLabel="name"
489
+ [(value)]="selectedId"
490
+ />
491
+ ```
492
+
493
+ ```typescript
494
+ options = [
495
+ { id: 1, name: 'Option 1' },
496
+ { id: 2, name: 'Option 2' },
497
+ { id: 3, name: 'Option 3' },
498
+ ];
499
+ selectedId = 1;
500
+ ```
501
+
502
+ Multi-select mode
503
+
504
+ ```html
505
+ <ga-data-select
506
+ multiple
507
+ placeholder="Select multiple"
508
+ [items]="options"
509
+ [(value)]="selectedValues"
510
+ />
511
+ ```
512
+
513
+ ```typescript
514
+ selectedValues = ['Option 1', 'Option 2'];
515
+ ```
516
+
517
+ Searchable with built-in filtering
518
+
519
+ ```html
520
+ <ga-data-select
521
+ searchable
522
+ clearable
523
+ placeholder="Search and select"
524
+ [items]="options"
525
+ bindLabel="name"
526
+ [(value)]="selected"
527
+ />
528
+ ```
529
+
530
+ Searchable with custom filtering (server-side)
531
+
532
+ ```html
533
+ <ga-data-select
534
+ searchable
535
+ customFilter
536
+ [items]="filteredOptions.value() ?? []"
537
+ [loading]="filteredOptions.isLoading()"
538
+ (searchValueChange)="searchText.set($event)"
539
+ [(value)]="selected"
540
+ />
541
+ ```
542
+
543
+ ```typescript
544
+ readonly searchText = signal<string | null>(null);
545
+ readonly filteredOptions = rxResource({
546
+ params: () => ({ searchText: this.searchText() }),
547
+ stream: ({ params }) => {
548
+ if (params.searchText === null) {
549
+ return of([]);
550
+ }
551
+ return this.http.get('/api/options', { params });
552
+ },
553
+ });
554
+ ```
555
+
556
+ Grouped options
557
+
558
+ ```html
559
+ <ga-data-select
560
+ [items]="options"
561
+ bindLabel="name"
562
+ groupBy="category"
563
+ [(value)]="selected"
564
+ />
565
+ ```
566
+
567
+ ```typescript
568
+ options = [
569
+ { category: 'Fruits', name: 'Apple' },
570
+ { category: 'Fruits', name: 'Banana' },
571
+ { category: 'Vegetables', name: 'Carrot' },
572
+ ];
573
+ ```
574
+
575
+ Disabled options
576
+
577
+ ```typescript
578
+ options = [
579
+ { value: 1, label: 'Option 1' },
580
+ { value: 2, label: 'Option 2', $disabled: true },
581
+ { value: 3, label: 'Option 3' },
582
+ ];
583
+ ```
584
+
585
+ Custom typeahead labels
586
+
587
+ ```typescript
588
+ options = [
589
+ {
590
+ code: 'EMP001',
591
+ name: 'John Smith',
592
+ $typeaheadLabel: 'John Smith EMP001',
593
+ },
594
+ ];
595
+ ```
596
+
597
+ Custom value template
598
+
599
+ ```html
600
+ <ga-data-select [items]="options" [(value)]="selected">
601
+ <ng-template gaDataSelectValueTpl let-label let-item="item">
602
+ <strong>{{ label }}</strong> - {{ item.description }}
603
+ </ng-template>
604
+ </ga-data-select>
605
+ ```
606
+
607
+ Custom option label template
608
+
609
+ ```html
610
+ <ga-data-select
611
+ [items]="options"
612
+ [(value)]="selected"
613
+ bindValue="id"
614
+ bindLabel="name"
615
+ >
616
+ <ng-template gaDataSelectOptionTpl let-label let-item="item">
617
+ {{ label }}: {{ item.description }}
618
+ </ng-template>
619
+ </ga-data-select>
620
+ ```
621
+
622
+ Custom optgroup label template
623
+
624
+ ```html
625
+ <ga-data-select [items]="options" groupBy="group" [(value)]="selected">
626
+ <ng-template gaDataSelectOptgroupLabelTpl let-label let-items="items">
627
+ <strong>{{ label }}</strong> ({{ items.length }} items)
628
+ </ng-template>
629
+ </ga-data-select>
630
+ ```
631
+
632
+ Angular Forms with required validation
633
+
634
+ ```html
635
+ <ga-data-select
636
+ placeholder="Select value"
637
+ [items]="options"
638
+ [(ngModel)]="value"
639
+ required
640
+ clearable
641
+ #ngModel="ngModel"
642
+ />
643
+ ```
644
+
645
+ With form field
646
+
647
+ ```html
648
+ <ga-form-field>
649
+ <ga-label>Select Option</ga-label>
650
+ <ga-data-select
651
+ placeholder="Choose..."
652
+ [items]="options"
653
+ [(ngModel)]="value"
654
+ />
655
+ </ga-form-field>
656
+ ```
657
+
658
+ Object values with comparison function
659
+
660
+ ```html
661
+ <ga-data-select
662
+ [items]="options"
663
+ [compareFn]="compareFn"
664
+ bindLabel="name"
665
+ [(value)]="selectedObject"
666
+ />
667
+ ```
668
+
669
+ ```typescript
670
+ options = [
671
+ { id: 1, name: 'Option 1' },
672
+ { id: 2, name: 'Option 2' },
673
+ ];
674
+ selectedObject = { id: 1, name: 'Option 1' };
675
+ compareFn = (a: any, b: any) => a?.id === b?.id;
676
+ ```
677
+
678
+ Infinite scroll with optionsEndReached
679
+
680
+ ```html
681
+ <ga-data-select
682
+ [items]="items"
683
+ [loading]="isLoading"
684
+ (optionsEndReached)="loadMore()"
685
+ [(value)]="selected"
686
+ />
687
+ ```
688
+
689
+ i18n configuration
690
+
691
+ ```typescript
692
+ // Static configuration
693
+ provideGaDataSelectI18n({
694
+ clearLabel: 'Clear',
695
+ searchInputLabel: 'Search',
696
+ noOptionsLabel: 'No results found',
697
+ });
698
+
699
+ // Factory function with injection context
700
+ provideGaDataSelectI18n(() => {
701
+ const i18n = inject(MyI18nService);
702
+ return {
703
+ clearLabel: i18n.translate('clear'),
704
+ searchInputLabel: i18n.translate('search'),
705
+ noOptionsLabel: i18n.translate('no-results'),
706
+ };
707
+ });
708
+ ```
709
+
289
710
  ## Form Field
290
711
 
291
712
  Form field components for creating accessible form inputs with labels and error handling.
@@ -745,7 +1166,7 @@ Icon buttons
745
1166
 
746
1167
  ## Select
747
1168
 
748
- Select components for dropdown selections with search and multi-select capabilities.
1169
+ Select components for dropdown selections with multi-select capabilities. Use for static selects where all options are loaded upfront.
749
1170
 
750
1171
  **Angular module: GaSelectModule**
751
1172
 
@@ -761,9 +1182,7 @@ Select component.
761
1182
  - `compareWith: (a: any, b: any) => boolean` - Value comparison function
762
1183
  - `leftIcon: GaIconData` - Left icon
763
1184
  - `multiple: boolean` - Multiple selection
764
- - `searchable: boolean` - Enable search
765
1185
  - `clearable: boolean` - Show clear button
766
- - `textValue: string` - Search text (searchable mode)
767
1186
 
768
1187
  ### `<ga-select-dropdown>`
769
1188
 
@@ -828,18 +1247,6 @@ Multi-select
828
1247
  </ga-select>
829
1248
  ```
830
1249
 
831
- Searchable select
832
-
833
- ```html
834
- <ga-select searchable clearable [(textValue)]="searchText" [(value)]="selected">
835
- <ga-select-dropdown>
836
- <ga-option *ngFor="let item of filteredItems" [value]="item"
837
- >{{ item.name }}</ga-option
838
- >
839
- </ga-select-dropdown>
840
- </ga-select>
841
- ```
842
-
843
1250
  Select with groups
844
1251
 
845
1252
  ```html