@openkit-labs/ngx-kit-ui 0.0.38 → 0.0.40
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.
|
@@ -2409,6 +2409,296 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
2409
2409
|
type: Output
|
|
2410
2410
|
}] } });
|
|
2411
2411
|
|
|
2412
|
+
class KitInputMultiSelectComponent extends KitBaseInputComponent {
|
|
2413
|
+
screenService;
|
|
2414
|
+
/**
|
|
2415
|
+
* Whether the field is required
|
|
2416
|
+
*/
|
|
2417
|
+
required = false;
|
|
2418
|
+
/**
|
|
2419
|
+
* Options dataset for the select component
|
|
2420
|
+
* Can be an array of objects or simple values
|
|
2421
|
+
*/
|
|
2422
|
+
options = [];
|
|
2423
|
+
/**
|
|
2424
|
+
* The field name to use for matching items (default: 'id' or '_id')
|
|
2425
|
+
*/
|
|
2426
|
+
matchField = 'id';
|
|
2427
|
+
/**
|
|
2428
|
+
* The field name to use as display text for each option (default: 'name')
|
|
2429
|
+
*/
|
|
2430
|
+
displayField = 'name';
|
|
2431
|
+
/**
|
|
2432
|
+
* Custom title text for the dialog/bottom sheet (default: 'Select an option')
|
|
2433
|
+
*/
|
|
2434
|
+
dialogTitle = 'Select an option';
|
|
2435
|
+
/**
|
|
2436
|
+
* Whether to show a search box at the top of the options list
|
|
2437
|
+
*/
|
|
2438
|
+
showSearchBox = false;
|
|
2439
|
+
searchField = null;
|
|
2440
|
+
searchBoxPlaceholder = 'Search options...';
|
|
2441
|
+
/**
|
|
2442
|
+
* Template references for custom rendering of options
|
|
2443
|
+
*/
|
|
2444
|
+
activeTemplate;
|
|
2445
|
+
inactiveTemplate;
|
|
2446
|
+
emptyTemplate;
|
|
2447
|
+
/**
|
|
2448
|
+
* Control states for dialogs and bottom sheets
|
|
2449
|
+
*/
|
|
2450
|
+
isBottomSheetOpen = false;
|
|
2451
|
+
isDialogOpen = false;
|
|
2452
|
+
/**
|
|
2453
|
+
* Track if the UI is on a small screen
|
|
2454
|
+
*/
|
|
2455
|
+
isSmallScreen = false;
|
|
2456
|
+
/**
|
|
2457
|
+
* Search functionality
|
|
2458
|
+
*/
|
|
2459
|
+
searchTerm = '';
|
|
2460
|
+
filteredOptions = [];
|
|
2461
|
+
/**
|
|
2462
|
+
* Keep track of our subscriptions
|
|
2463
|
+
*/
|
|
2464
|
+
screenSubscription = null;
|
|
2465
|
+
constructor(screenService, ngControl = null) {
|
|
2466
|
+
super(ngControl);
|
|
2467
|
+
this.screenService = screenService;
|
|
2468
|
+
// Subscribe to screen size changes
|
|
2469
|
+
effect(() => {
|
|
2470
|
+
const isSmall = this.screenService.isSmall();
|
|
2471
|
+
this.isSmallScreen = isSmall;
|
|
2472
|
+
});
|
|
2473
|
+
}
|
|
2474
|
+
ngOnInit() {
|
|
2475
|
+
super.ngOnInit();
|
|
2476
|
+
// Initialize filtered options
|
|
2477
|
+
this.filteredOptions = [...this.options];
|
|
2478
|
+
}
|
|
2479
|
+
ngOnChanges(changes) {
|
|
2480
|
+
if (changes['options'] && this.options) {
|
|
2481
|
+
this.filteredOptions = [...this.options];
|
|
2482
|
+
// Reapply search filter if there's an active search
|
|
2483
|
+
if (this.searchTerm) {
|
|
2484
|
+
this.filterOptions();
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
ngOnDestroy() {
|
|
2489
|
+
// Clean up subscription
|
|
2490
|
+
if (this.screenSubscription) {
|
|
2491
|
+
this.screenSubscription.unsubscribe();
|
|
2492
|
+
this.screenSubscription = null;
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
/**
|
|
2496
|
+
* Return the component prefix for ID generation
|
|
2497
|
+
*/
|
|
2498
|
+
getComponentPrefix() {
|
|
2499
|
+
return 'input-multi-select';
|
|
2500
|
+
}
|
|
2501
|
+
/**
|
|
2502
|
+
* Opens the appropriate selection UI based on screen size
|
|
2503
|
+
*/
|
|
2504
|
+
openSelect() {
|
|
2505
|
+
// Reset search when opening
|
|
2506
|
+
this.searchTerm = '';
|
|
2507
|
+
this.filteredOptions = [...this.options];
|
|
2508
|
+
if (this.isSmallScreen) {
|
|
2509
|
+
this.isBottomSheetOpen = true;
|
|
2510
|
+
this.isDialogOpen = false;
|
|
2511
|
+
}
|
|
2512
|
+
else {
|
|
2513
|
+
this.isDialogOpen = true;
|
|
2514
|
+
this.isBottomSheetOpen = false;
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
/**
|
|
2518
|
+
* Handle keyboard events for accessibility
|
|
2519
|
+
*/
|
|
2520
|
+
onKeyDown(event) {
|
|
2521
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
2522
|
+
event.preventDefault();
|
|
2523
|
+
this.openSelect();
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
/**
|
|
2527
|
+
* Closes all selection UIs
|
|
2528
|
+
*/
|
|
2529
|
+
closeSelect() {
|
|
2530
|
+
setTimeout(() => {
|
|
2531
|
+
this.isBottomSheetOpen = false;
|
|
2532
|
+
this.isDialogOpen = false;
|
|
2533
|
+
// Reset search when closing
|
|
2534
|
+
this.searchTerm = '';
|
|
2535
|
+
this.filteredOptions = [...this.options];
|
|
2536
|
+
}, 250);
|
|
2537
|
+
}
|
|
2538
|
+
/**
|
|
2539
|
+
* Handle search input changes
|
|
2540
|
+
*/
|
|
2541
|
+
onSearchChange(searchTerm) {
|
|
2542
|
+
this.searchTerm = searchTerm;
|
|
2543
|
+
this.filterOptions();
|
|
2544
|
+
}
|
|
2545
|
+
/**
|
|
2546
|
+
* Filter options based on search term
|
|
2547
|
+
*/
|
|
2548
|
+
filterOptions() {
|
|
2549
|
+
if (!this.searchTerm.trim()) {
|
|
2550
|
+
this.filteredOptions = [...this.options];
|
|
2551
|
+
return;
|
|
2552
|
+
}
|
|
2553
|
+
const searchLower = this.searchTerm.toLowerCase().trim();
|
|
2554
|
+
this.filteredOptions = this.options.filter(option => {
|
|
2555
|
+
const searchValue = this.getSearchValue(option).toLowerCase();
|
|
2556
|
+
return searchValue.includes(searchLower);
|
|
2557
|
+
});
|
|
2558
|
+
}
|
|
2559
|
+
/**
|
|
2560
|
+
* Get the search value for the option
|
|
2561
|
+
* Uses searchField if defined, otherwise falls back to displayField
|
|
2562
|
+
*/
|
|
2563
|
+
getSearchValue(option) {
|
|
2564
|
+
if (this.isPrimitive(option)) {
|
|
2565
|
+
return String(option);
|
|
2566
|
+
}
|
|
2567
|
+
const objWithKey = option;
|
|
2568
|
+
const fieldToSearch = this.searchField || this.displayField;
|
|
2569
|
+
return String(objWithKey[fieldToSearch] || 'Unknown Option');
|
|
2570
|
+
}
|
|
2571
|
+
/**
|
|
2572
|
+
* Handle option selection
|
|
2573
|
+
* This will be used inside the dialog/bottom sheet
|
|
2574
|
+
*/
|
|
2575
|
+
onOptionSelect(option) {
|
|
2576
|
+
const currentValue = this.value || [];
|
|
2577
|
+
const isSelected = this.isSelected(option);
|
|
2578
|
+
let newValue;
|
|
2579
|
+
if (isSelected) {
|
|
2580
|
+
// Remove the option from the selection
|
|
2581
|
+
newValue = currentValue.filter(item => !this.isSameOption(item, option));
|
|
2582
|
+
}
|
|
2583
|
+
else {
|
|
2584
|
+
// Add the option to the selection
|
|
2585
|
+
newValue = [...currentValue, option];
|
|
2586
|
+
}
|
|
2587
|
+
// Update the value using the base class method for proper form integration
|
|
2588
|
+
this.onValueChange(newValue);
|
|
2589
|
+
}
|
|
2590
|
+
/**
|
|
2591
|
+
* Check if two options are the same
|
|
2592
|
+
*/
|
|
2593
|
+
isSameOption(option1, option2) {
|
|
2594
|
+
if (this.isPrimitive(option1) && this.isPrimitive(option2)) {
|
|
2595
|
+
return String(option1) === String(option2);
|
|
2596
|
+
}
|
|
2597
|
+
const obj1 = option1;
|
|
2598
|
+
const obj2 = option2;
|
|
2599
|
+
const idField = obj1[this.matchField] !== undefined ? this.matchField : '_id';
|
|
2600
|
+
return obj1 && obj2 &&
|
|
2601
|
+
obj1[idField] !== undefined &&
|
|
2602
|
+
obj2[idField] !== undefined &&
|
|
2603
|
+
String(obj1[idField]) === String(obj2[idField]);
|
|
2604
|
+
}
|
|
2605
|
+
/**
|
|
2606
|
+
* Get the display value for the option
|
|
2607
|
+
*/
|
|
2608
|
+
getDisplayValue() {
|
|
2609
|
+
if (!this.value || this.value.length === 0) {
|
|
2610
|
+
return '';
|
|
2611
|
+
}
|
|
2612
|
+
if (this.value.length === 1) {
|
|
2613
|
+
return this.getOptionDisplay(this.value[0]);
|
|
2614
|
+
}
|
|
2615
|
+
return `${this.value.length} items selected`;
|
|
2616
|
+
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Get the display value for a single option
|
|
2619
|
+
*/
|
|
2620
|
+
getOptionDisplay(option) {
|
|
2621
|
+
if (this.isPrimitive(option)) {
|
|
2622
|
+
return String(option);
|
|
2623
|
+
}
|
|
2624
|
+
const objWithKey = option;
|
|
2625
|
+
return String(objWithKey[this.displayField] || 'Unknown Option');
|
|
2626
|
+
}
|
|
2627
|
+
/**
|
|
2628
|
+
* Check if the current value matches the option
|
|
2629
|
+
*/
|
|
2630
|
+
isSelected(option) {
|
|
2631
|
+
if (!this.value || this.value.length === 0) {
|
|
2632
|
+
return false;
|
|
2633
|
+
}
|
|
2634
|
+
return this.value.some(item => this.isSameOption(item, option));
|
|
2635
|
+
}
|
|
2636
|
+
/**
|
|
2637
|
+
* Check if a value is a primitive type
|
|
2638
|
+
*/
|
|
2639
|
+
isPrimitive(value) {
|
|
2640
|
+
return (typeof value === 'string' ||
|
|
2641
|
+
typeof value === 'number' ||
|
|
2642
|
+
typeof value === 'boolean');
|
|
2643
|
+
}
|
|
2644
|
+
getDefaultValue() {
|
|
2645
|
+
return [];
|
|
2646
|
+
}
|
|
2647
|
+
hasCustomActiveTemplate() {
|
|
2648
|
+
return !!this.activeTemplate;
|
|
2649
|
+
}
|
|
2650
|
+
hasCustomInactiveTemplate() {
|
|
2651
|
+
return !!this.inactiveTemplate;
|
|
2652
|
+
}
|
|
2653
|
+
hasCustomEmptyTemplate() {
|
|
2654
|
+
return !!this.emptyTemplate;
|
|
2655
|
+
}
|
|
2656
|
+
/**
|
|
2657
|
+
* Get the context for template rendering
|
|
2658
|
+
*/
|
|
2659
|
+
getOptionContext(option) {
|
|
2660
|
+
return {
|
|
2661
|
+
option,
|
|
2662
|
+
isSelected: this.isSelected(option)
|
|
2663
|
+
};
|
|
2664
|
+
}
|
|
2665
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: KitInputMultiSelectComponent, deps: [{ token: KitScreenService }, { token: i1.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
2666
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: KitInputMultiSelectComponent, isStandalone: true, selector: "kit-input-multi-select", inputs: { required: "required", options: "options", matchField: "matchField", displayField: "displayField", dialogTitle: "dialogTitle", showSearchBox: "showSearchBox", searchField: "searchField", searchBoxPlaceholder: "searchBoxPlaceholder" }, queries: [{ propertyName: "activeTemplate", first: true, predicate: KitSelectItemActiveDirective, descendants: true, read: TemplateRef }, { propertyName: "inactiveTemplate", first: true, predicate: KitSelectItemDirective, descendants: true, read: TemplateRef }, { propertyName: "emptyTemplate", first: true, predicate: KitSelectEmptyDirective, descendants: true, read: TemplateRef }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "@if(title){\n<kit-input-field-title [for]=\"id\"\n [required]=\"required\"\n [disabled]=\"disabled\">\n {{ title }}\n</kit-input-field-title>\n}\n\n<!-- Custom select that opens the appropriate UI based on screen size -->\n<div class=\"kit-input-select-container\"\n [id]=\"id\"\n [attr.aria-label]=\"title\"\n [attr.aria-required]=\"required\"\n [attr.aria-invalid]=\"hasError || null\"\n [class.disabled]=\"disabled\"\n [class.error]=\"hasError\"\n tabindex=\"0\"\n (click)=\"!disabled && openSelect()\"\n (keydown)=\"!disabled && onKeyDown($event)\"\n (focus)=\"onFocus($event)\"\n (blur)=\"onBlur($event)\">\n\n <div class=\"kit-input-select\"\n [class.has-error]=\"hasError\"\n [class.disabled]=\"disabled\">\n {{ getDisplayValue() || (placeholder || 'Select...') }}\n </div>\n\n</div>\n\n@if(helperText && !hasError){\n<kit-text-caption class=\"helper-text\">\n {{ helperText }}\n</kit-text-caption>\n}\n\n@if(hasError && effectiveErrorMessage){\n<kit-text-caption class=\"error-message\">\n {{ effectiveErrorMessage }}\n</kit-text-caption>\n}\n\n<!-- Dialog for larger screens -->\n<kit-dialog [(isOpen)]=\"isDialogOpen\">\n <div>\n <div class=\"kit-dialog-header\">\n <kit-text-label margin=\"5px\">{{ dialogTitle || title }}</kit-text-label>\n </div>\n\n <!-- Search input -->\n @if(showSearchBox){\n <div class=\"kit-select-search-container\">\n <kit-input-text [(value)]=\"searchTerm\"\n (valueChange)=\"onSearchChange($event)\"\n [placeholder]=\"searchBoxPlaceholder\"></kit-input-text>\n </div>\n }\n\n <div class=\"kit-select-options\">\n @for(option of filteredOptions; track option){\n <div class=\"kit-select-item\"\n [class.selected]=\"isSelected(option)\"\n (click)=\"onOptionSelect(option)\">\n <div class=\"kit-checkbox\">\n <svg class=\"kit-checkbox-check\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\">\n <path d=\"M20 6L9 17L4 12\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n <span class=\"kit-select-item-text\">{{ getOptionDisplay(option) }}</span>\n </div>\n }\n\n @if(filteredOptions.length === 0){\n <div class=\"kit-select-options\">\n <kit-text-caption>No options found</kit-text-caption>\n </div>\n }\n </div>\n </div>\n</kit-dialog>\n\n<!-- Bottom sheet for small screens -->\n<kit-bottom-sheet [(isOpen)]=\"isBottomSheetOpen\">\n <div>\n <div class=\"kit-bottom-sheet-header\">\n <kit-text-label margin=\"5px\">{{ dialogTitle || title }}</kit-text-label>\n </div>\n\n <!-- Search input -->\n @if(showSearchBox){\n <div class=\"kit-select-search-container\">\n <kit-input-text [(value)]=\"searchTerm\"\n (valueChange)=\"onSearchChange($event)\"\n [placeholder]=\"searchBoxPlaceholder\"></kit-input-text>\n </div>\n }\n\n <div class=\"kit-select-options\">\n @for(option of filteredOptions; track option){\n <div class=\"kit-select-item\"\n [class.selected]=\"isSelected(option)\"\n (click)=\"onOptionSelect(option)\">\n <div class=\"kit-checkbox\">\n <svg class=\"kit-checkbox-check\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\">\n <path d=\"M20 6L9 17L4 12\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n <span class=\"kit-select-item-text\">{{ getOptionDisplay(option) }}</span>\n </div>\n }\n\n @if(filteredOptions.length === 0){\n <div class=\"kit-select-options\">\n <kit-text-caption>No options found</kit-text-caption>\n </div>\n }\n </div>\n </div>\n</kit-bottom-sheet>", styles: [":host{display:block;width:100%}.kit-input-select-container{position:relative;width:100%;display:flex;align-items:center}.kit-input-select{width:100%;box-sizing:border-box;padding:var(--kit-input-padding, 12px 16px);font-size:var(--kit-input-font-size, 1rem);line-height:var(--kit-input-line-height, 1.5);color:var(--kit-input-text-color, #212529);background-color:var(--kit-input-background-color, #e8e8e8);border:var(--kit-input-border-width, 2px) solid var(--kit-input-border-color, transparent);border-radius:var(--kit-input-border-radius, 16px);transition:border-color .2s ease-in-out;padding-right:40px}.kit-input-select::placeholder{color:var(--kit-input-placeholder-color, var(--kit-text-color-secondary, #6c757d));opacity:1}.kit-input-select:focus{outline:none;border-color:var(--kit-input-focus-border-color, var(--kit-color-primary, #0066cc))}.kit-input-select.has-error{border-color:var(--kit-input-error-border-color, var(--kit-color-danger, #dc3545));background-color:var(--kit-input-error-background-color, #fce8ea)}.kit-input-select:disabled,.kit-input-select.disabled{background-color:var(--kit-input-disabled-background-color, #f5f5f5);color:var(--kit-input-disabled-text-color, var(--kit-text-color-muted, #adb5bd));cursor:not-allowed}.kit-input-select:disabled::placeholder,.kit-input-select.disabled::placeholder{color:var(--kit-input-disabled-placeholder-color, var(--kit-text-color-muted, #adb5bd))}.kit-dialog-header,.kit-bottom-sheet-header{display:flex;justify-content:space-between;align-items:center}.kit-dialog-close,.kit-bottom-sheet-close{background:none;border:none;cursor:pointer;padding:8px}.kit-select-options{display:flex;flex-direction:column;gap:4px;padding:8px 0;overflow-y:auto;box-sizing:border-box}.kit-select-item{display:flex;align-items:center;width:100%;box-sizing:border-box;padding:var(--kit-select-item-padding, 12px 16px);font-size:var(--kit-select-item-font-size, var(--kit-font-size-body, 1rem));color:var(--kit-select-item-text-color, var(--kit-text-color-primary, #212529));background-color:var(--kit-select-item-background-color, transparent);border-radius:var(--kit-select-item-border-radius, 14px);border:none;outline:none;flex-shrink:0}.kit-select-item:hover{background-color:var(--kit-select-item-hover-background-color, rgba(0, 102, 204, .1))}.kit-checkbox{width:20px;height:20px;border:2px solid var(--kit-input-border-color, #adb5bd);border-radius:4px;display:flex;align-items:center;justify-content:center;margin-right:12px;transition:background-color .2s,border-color .2s}.kit-checkbox-check{display:none;color:#fff}.kit-select-item.selected .kit-checkbox{background-color:var(--kit-color-primary, #0066cc);border-color:var(--kit-color-primary, #0066cc)}.kit-select-item.selected .kit-checkbox-check{display:block}.kit-select-item-custom{display:block;width:100%;border:none;outline:none;box-sizing:border-box}.kit-select-item-text{flex:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kit-select-search-container{padding-top:5px;padding-bottom:5px}\n"], dependencies: [{ kind: "component", type: KitInputFieldTitleComponent, selector: "kit-input-field-title", inputs: ["for", "required", "disabled"] }, { kind: "component", type: KitTextCaptionComponent, selector: "kit-text-caption", inputs: ["color", "align", "weight", "decoration", "margin", "wrap", "ellipses", "lines", "italic"] }, { kind: "ngmodule", type: KitOverlaysModule }, { kind: "component", type: KitBottomSheetComponent, selector: "kit-bottom-sheet", inputs: ["isOpen", "closeOnBackdropClick", "padding", "maxHeight"], outputs: ["isOpenChange"] }, { kind: "component", type: KitDialogComponent, selector: "kit-dialog", inputs: ["isOpen", "fullscreen", "closeOnBackdropClick", "padding"], outputs: ["isOpenChange"] }, { kind: "component", type: KitTextLabelComponent, selector: "kit-text-label", inputs: ["color", "align", "weight", "decoration", "margin", "wrap", "ellipses", "lines", "italic"] }, { kind: "component", type: KitInputTextComponent, selector: "kit-input-text", inputs: ["required"], outputs: ["paste"] }] });
|
|
2667
|
+
}
|
|
2668
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: KitInputMultiSelectComponent, decorators: [{
|
|
2669
|
+
type: Component,
|
|
2670
|
+
args: [{ selector: 'kit-input-multi-select', standalone: true, imports: [KitInputFieldTitleComponent, KitTextCaptionComponent, KitOverlaysModule, KitTextLabelComponent, KitInputTextComponent], template: "@if(title){\n<kit-input-field-title [for]=\"id\"\n [required]=\"required\"\n [disabled]=\"disabled\">\n {{ title }}\n</kit-input-field-title>\n}\n\n<!-- Custom select that opens the appropriate UI based on screen size -->\n<div class=\"kit-input-select-container\"\n [id]=\"id\"\n [attr.aria-label]=\"title\"\n [attr.aria-required]=\"required\"\n [attr.aria-invalid]=\"hasError || null\"\n [class.disabled]=\"disabled\"\n [class.error]=\"hasError\"\n tabindex=\"0\"\n (click)=\"!disabled && openSelect()\"\n (keydown)=\"!disabled && onKeyDown($event)\"\n (focus)=\"onFocus($event)\"\n (blur)=\"onBlur($event)\">\n\n <div class=\"kit-input-select\"\n [class.has-error]=\"hasError\"\n [class.disabled]=\"disabled\">\n {{ getDisplayValue() || (placeholder || 'Select...') }}\n </div>\n\n</div>\n\n@if(helperText && !hasError){\n<kit-text-caption class=\"helper-text\">\n {{ helperText }}\n</kit-text-caption>\n}\n\n@if(hasError && effectiveErrorMessage){\n<kit-text-caption class=\"error-message\">\n {{ effectiveErrorMessage }}\n</kit-text-caption>\n}\n\n<!-- Dialog for larger screens -->\n<kit-dialog [(isOpen)]=\"isDialogOpen\">\n <div>\n <div class=\"kit-dialog-header\">\n <kit-text-label margin=\"5px\">{{ dialogTitle || title }}</kit-text-label>\n </div>\n\n <!-- Search input -->\n @if(showSearchBox){\n <div class=\"kit-select-search-container\">\n <kit-input-text [(value)]=\"searchTerm\"\n (valueChange)=\"onSearchChange($event)\"\n [placeholder]=\"searchBoxPlaceholder\"></kit-input-text>\n </div>\n }\n\n <div class=\"kit-select-options\">\n @for(option of filteredOptions; track option){\n <div class=\"kit-select-item\"\n [class.selected]=\"isSelected(option)\"\n (click)=\"onOptionSelect(option)\">\n <div class=\"kit-checkbox\">\n <svg class=\"kit-checkbox-check\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\">\n <path d=\"M20 6L9 17L4 12\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n <span class=\"kit-select-item-text\">{{ getOptionDisplay(option) }}</span>\n </div>\n }\n\n @if(filteredOptions.length === 0){\n <div class=\"kit-select-options\">\n <kit-text-caption>No options found</kit-text-caption>\n </div>\n }\n </div>\n </div>\n</kit-dialog>\n\n<!-- Bottom sheet for small screens -->\n<kit-bottom-sheet [(isOpen)]=\"isBottomSheetOpen\">\n <div>\n <div class=\"kit-bottom-sheet-header\">\n <kit-text-label margin=\"5px\">{{ dialogTitle || title }}</kit-text-label>\n </div>\n\n <!-- Search input -->\n @if(showSearchBox){\n <div class=\"kit-select-search-container\">\n <kit-input-text [(value)]=\"searchTerm\"\n (valueChange)=\"onSearchChange($event)\"\n [placeholder]=\"searchBoxPlaceholder\"></kit-input-text>\n </div>\n }\n\n <div class=\"kit-select-options\">\n @for(option of filteredOptions; track option){\n <div class=\"kit-select-item\"\n [class.selected]=\"isSelected(option)\"\n (click)=\"onOptionSelect(option)\">\n <div class=\"kit-checkbox\">\n <svg class=\"kit-checkbox-check\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\">\n <path d=\"M20 6L9 17L4 12\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n <span class=\"kit-select-item-text\">{{ getOptionDisplay(option) }}</span>\n </div>\n }\n\n @if(filteredOptions.length === 0){\n <div class=\"kit-select-options\">\n <kit-text-caption>No options found</kit-text-caption>\n </div>\n }\n </div>\n </div>\n</kit-bottom-sheet>", styles: [":host{display:block;width:100%}.kit-input-select-container{position:relative;width:100%;display:flex;align-items:center}.kit-input-select{width:100%;box-sizing:border-box;padding:var(--kit-input-padding, 12px 16px);font-size:var(--kit-input-font-size, 1rem);line-height:var(--kit-input-line-height, 1.5);color:var(--kit-input-text-color, #212529);background-color:var(--kit-input-background-color, #e8e8e8);border:var(--kit-input-border-width, 2px) solid var(--kit-input-border-color, transparent);border-radius:var(--kit-input-border-radius, 16px);transition:border-color .2s ease-in-out;padding-right:40px}.kit-input-select::placeholder{color:var(--kit-input-placeholder-color, var(--kit-text-color-secondary, #6c757d));opacity:1}.kit-input-select:focus{outline:none;border-color:var(--kit-input-focus-border-color, var(--kit-color-primary, #0066cc))}.kit-input-select.has-error{border-color:var(--kit-input-error-border-color, var(--kit-color-danger, #dc3545));background-color:var(--kit-input-error-background-color, #fce8ea)}.kit-input-select:disabled,.kit-input-select.disabled{background-color:var(--kit-input-disabled-background-color, #f5f5f5);color:var(--kit-input-disabled-text-color, var(--kit-text-color-muted, #adb5bd));cursor:not-allowed}.kit-input-select:disabled::placeholder,.kit-input-select.disabled::placeholder{color:var(--kit-input-disabled-placeholder-color, var(--kit-text-color-muted, #adb5bd))}.kit-dialog-header,.kit-bottom-sheet-header{display:flex;justify-content:space-between;align-items:center}.kit-dialog-close,.kit-bottom-sheet-close{background:none;border:none;cursor:pointer;padding:8px}.kit-select-options{display:flex;flex-direction:column;gap:4px;padding:8px 0;overflow-y:auto;box-sizing:border-box}.kit-select-item{display:flex;align-items:center;width:100%;box-sizing:border-box;padding:var(--kit-select-item-padding, 12px 16px);font-size:var(--kit-select-item-font-size, var(--kit-font-size-body, 1rem));color:var(--kit-select-item-text-color, var(--kit-text-color-primary, #212529));background-color:var(--kit-select-item-background-color, transparent);border-radius:var(--kit-select-item-border-radius, 14px);border:none;outline:none;flex-shrink:0}.kit-select-item:hover{background-color:var(--kit-select-item-hover-background-color, rgba(0, 102, 204, .1))}.kit-checkbox{width:20px;height:20px;border:2px solid var(--kit-input-border-color, #adb5bd);border-radius:4px;display:flex;align-items:center;justify-content:center;margin-right:12px;transition:background-color .2s,border-color .2s}.kit-checkbox-check{display:none;color:#fff}.kit-select-item.selected .kit-checkbox{background-color:var(--kit-color-primary, #0066cc);border-color:var(--kit-color-primary, #0066cc)}.kit-select-item.selected .kit-checkbox-check{display:block}.kit-select-item-custom{display:block;width:100%;border:none;outline:none;box-sizing:border-box}.kit-select-item-text{flex:1;text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kit-select-search-container{padding-top:5px;padding-bottom:5px}\n"] }]
|
|
2671
|
+
}], ctorParameters: () => [{ type: KitScreenService }, { type: i1.NgControl, decorators: [{
|
|
2672
|
+
type: Optional
|
|
2673
|
+
}, {
|
|
2674
|
+
type: Self
|
|
2675
|
+
}] }], propDecorators: { required: [{
|
|
2676
|
+
type: Input
|
|
2677
|
+
}], options: [{
|
|
2678
|
+
type: Input
|
|
2679
|
+
}], matchField: [{
|
|
2680
|
+
type: Input
|
|
2681
|
+
}], displayField: [{
|
|
2682
|
+
type: Input
|
|
2683
|
+
}], dialogTitle: [{
|
|
2684
|
+
type: Input
|
|
2685
|
+
}], showSearchBox: [{
|
|
2686
|
+
type: Input
|
|
2687
|
+
}], searchField: [{
|
|
2688
|
+
type: Input
|
|
2689
|
+
}], searchBoxPlaceholder: [{
|
|
2690
|
+
type: Input
|
|
2691
|
+
}], activeTemplate: [{
|
|
2692
|
+
type: ContentChild,
|
|
2693
|
+
args: [KitSelectItemActiveDirective, { read: TemplateRef }]
|
|
2694
|
+
}], inactiveTemplate: [{
|
|
2695
|
+
type: ContentChild,
|
|
2696
|
+
args: [KitSelectItemDirective, { read: TemplateRef }]
|
|
2697
|
+
}], emptyTemplate: [{
|
|
2698
|
+
type: ContentChild,
|
|
2699
|
+
args: [KitSelectEmptyDirective, { read: TemplateRef }]
|
|
2700
|
+
}] } });
|
|
2701
|
+
|
|
2412
2702
|
class KitInputTextareaComponent extends KitBaseInputComponent {
|
|
2413
2703
|
/**
|
|
2414
2704
|
* Whether the field is required
|
|
@@ -2526,6 +2816,7 @@ class KitInputModule {
|
|
|
2526
2816
|
KitInputOtpComponent,
|
|
2527
2817
|
KitInputPhoneComponent,
|
|
2528
2818
|
KitInputSelectComponent,
|
|
2819
|
+
KitInputMultiSelectComponent,
|
|
2529
2820
|
KitSelectItemDirective,
|
|
2530
2821
|
KitSelectItemActiveDirective,
|
|
2531
2822
|
KitInputTimeComponent,
|
|
@@ -2537,6 +2828,7 @@ class KitInputModule {
|
|
|
2537
2828
|
KitInputOtpComponent,
|
|
2538
2829
|
KitInputPhoneComponent,
|
|
2539
2830
|
KitInputSelectComponent,
|
|
2831
|
+
KitInputMultiSelectComponent,
|
|
2540
2832
|
KitSelectItemDirective,
|
|
2541
2833
|
KitSelectItemActiveDirective,
|
|
2542
2834
|
KitInputTimeComponent,
|
|
@@ -2559,6 +2851,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
2559
2851
|
KitInputOtpComponent,
|
|
2560
2852
|
KitInputPhoneComponent,
|
|
2561
2853
|
KitInputSelectComponent,
|
|
2854
|
+
KitInputMultiSelectComponent,
|
|
2562
2855
|
KitSelectItemDirective,
|
|
2563
2856
|
KitSelectItemActiveDirective,
|
|
2564
2857
|
KitInputTimeComponent,
|
|
@@ -2573,6 +2866,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
2573
2866
|
KitInputOtpComponent,
|
|
2574
2867
|
KitInputPhoneComponent,
|
|
2575
2868
|
KitInputSelectComponent,
|
|
2869
|
+
KitInputMultiSelectComponent,
|
|
2576
2870
|
KitSelectItemDirective,
|
|
2577
2871
|
KitSelectItemActiveDirective,
|
|
2578
2872
|
KitInputTimeComponent,
|
|
@@ -5639,5 +5933,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
5639
5933
|
* Generated bundle index. Do not edit.
|
|
5640
5934
|
*/
|
|
5641
5935
|
|
|
5642
|
-
export { KitAppRootComponent, KitAvatarComponent, KitBadgeComponent, KitBaseInputComponent, KitBottomBarComponent, KitBottomSheetComponent, KitButtonComponent, KitButtonGroupComponent, KitButtonGroupItemActiveDirective, KitButtonGroupItemComponent, KitButtonGroupItemIdleDirective, KitButtonModule, KitCardComponent, KitCarouselComponent, KitCenterComponent, KitColumnComponent, KitConstrainedBoxComponent, KitContainerComponent, KitCopyToClipboardDirective, KitDataModule, KitDialogComponent, KitDirectivesModule, KitDividerComponent, KitExpandedComponent, KitFileSizePipe, KitFloatingActionButtonComponent, KitGestureDetectorComponent, KitGridComponent, KitImageComponent, KitImageErrorDirective, KitImageLoadingDirective, KitInputDateComponent, KitInputEmailComponent, KitInputFieldTitleComponent, KitInputModule, KitInputNumberComponent, KitInputOtpComponent, KitInputPasswordComponent, KitInputPhoneComponent, KitInputSelectComponent, KitInputTextComponent, KitInputTextareaComponent, KitInputTimeComponent, KitInteractorsModule, KitKMBPipe, KitLayoutModule, KitMediaModule, KitNavigationModule, KitNavigationService, KitOverlaysModule, KitPaddingComponent, KitPageComponent, KitPanelModule, KitPipesModule, KitPositionedComponent, KitPressAndHoldDirective, KitProgressBarComponent, KitRadioButtonComponent, KitRoundButtonComponent, KitRouterOutletComponent, KitRowComponent, KitScreenService, KitSelectItemActiveDirective, KitSelectItemDirective, KitSideMenuComponent, KitSideMenuService, KitSizedBoxComponent, KitSpacerComponent, KitStickyContainerComponent, KitTabContentComponent, KitTabViewComponent, KitTextBodyComponent, KitTextButtonComponent, KitTextCaptionComponent, KitTextDisplayComponent, KitTextHeadingComponent, KitTextLabelComponent, KitTextLinkComponent, KitTextModule, KitTextSubheadingComponent, KitThemeService, KitTimeAgoPipe, KitTopBarComponent, SimpleTableComponent, StackComponent };
|
|
5936
|
+
export { KitAppRootComponent, KitAvatarComponent, KitBadgeComponent, KitBaseInputComponent, KitBottomBarComponent, KitBottomSheetComponent, KitButtonComponent, KitButtonGroupComponent, KitButtonGroupItemActiveDirective, KitButtonGroupItemComponent, KitButtonGroupItemIdleDirective, KitButtonModule, KitCardComponent, KitCarouselComponent, KitCenterComponent, KitColumnComponent, KitConstrainedBoxComponent, KitContainerComponent, KitCopyToClipboardDirective, KitDataModule, KitDialogComponent, KitDirectivesModule, KitDividerComponent, KitExpandedComponent, KitFileSizePipe, KitFloatingActionButtonComponent, KitGestureDetectorComponent, KitGridComponent, KitImageComponent, KitImageErrorDirective, KitImageLoadingDirective, KitInputDateComponent, KitInputEmailComponent, KitInputFieldTitleComponent, KitInputModule, KitInputMultiSelectComponent, KitInputNumberComponent, KitInputOtpComponent, KitInputPasswordComponent, KitInputPhoneComponent, KitInputSelectComponent, KitInputTextComponent, KitInputTextareaComponent, KitInputTimeComponent, KitInteractorsModule, KitKMBPipe, KitLayoutModule, KitMediaModule, KitNavigationModule, KitNavigationService, KitOverlaysModule, KitPaddingComponent, KitPageComponent, KitPanelModule, KitPipesModule, KitPositionedComponent, KitPressAndHoldDirective, KitProgressBarComponent, KitRadioButtonComponent, KitRoundButtonComponent, KitRouterOutletComponent, KitRowComponent, KitScreenService, KitSelectItemActiveDirective, KitSelectItemDirective, KitSideMenuComponent, KitSideMenuService, KitSizedBoxComponent, KitSpacerComponent, KitStickyContainerComponent, KitTabContentComponent, KitTabViewComponent, KitTextBodyComponent, KitTextButtonComponent, KitTextCaptionComponent, KitTextDisplayComponent, KitTextHeadingComponent, KitTextLabelComponent, KitTextLinkComponent, KitTextModule, KitTextSubheadingComponent, KitThemeService, KitTimeAgoPipe, KitTopBarComponent, SimpleTableComponent, StackComponent };
|
|
5643
5937
|
//# sourceMappingURL=openkit-labs-ngx-kit-ui.mjs.map
|