@brickclay-org/ui 0.1.73 → 0.1.75
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/fesm2022/brickclay-org-ui.mjs +955 -211
- package/fesm2022/brickclay-org-ui.mjs.map +1 -1
- package/index.d.ts +511 -172
- package/package.json +1 -1
- package/src/lib/hierarchical-select/hierarchical-select.css +29 -8
- package/src/lib/menu/menu.css +55 -95
- package/src/lib/select/select.css +46 -5
- package/src/lib/ui-avatar/ui-avatar.css +11 -4
- package/src/styles.css +3 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, EventEmitter, forwardRef, HostListener, ViewChild, Input, Output, Injectable, NgModule, ViewEncapsulation, Optional, Self, Directive, input, model, output, signal, computed, effect, inject, ElementRef, ViewChildren, InjectionToken, createComponent
|
|
2
|
+
import { Component, EventEmitter, forwardRef, HostListener, ViewChild, Input, Output, Injectable, NgModule, ViewEncapsulation, Optional, Self, Directive, ChangeDetectionStrategy, input, model, output, signal, computed, effect, inject, ElementRef, ViewChildren, InjectionToken, createComponent } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule, NgClass } from '@angular/common';
|
|
5
|
-
import * as
|
|
5
|
+
import * as i2 from '@angular/forms';
|
|
6
6
|
import { FormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
|
|
7
7
|
import moment from 'moment';
|
|
8
8
|
import { Subject, filter } from 'rxjs';
|
|
9
|
-
import * as i2 from '@angular/cdk/drag-drop';
|
|
9
|
+
import * as i2$1 from '@angular/cdk/drag-drop';
|
|
10
10
|
import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
|
|
11
11
|
import * as i1$1 from '@angular/cdk/scrolling';
|
|
12
12
|
import { ScrollingModule, CdkScrollable } from '@angular/cdk/scrolling';
|
|
@@ -3056,7 +3056,7 @@ class BkCustomCalendar {
|
|
|
3056
3056
|
useExisting: forwardRef(() => BkCustomCalendar),
|
|
3057
3057
|
multi: true,
|
|
3058
3058
|
},
|
|
3059
|
-
], viewQueries: [{ propertyName: "inputWrapper", first: true, predicate: ["inputWrapper"], descendants: true }, { propertyName: "calendarPopupRef", first: true, predicate: ["calendarPopup"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"calendar-container relative\" [class.open]=\"show\" [class.inline-mode]=\"inline\" [class.disabled]=\"disabled\">\r\n <!-- Input field -->\r\n <div #inputWrapper class=\"input-wrapper\" *ngIf=\"!inline\">\r\n <input\r\n type=\"text\"\r\n (click)=\"!disabled && toggle()\"\r\n (keydown.enter)=\"$event.preventDefault()\"\r\n (blur)=\"markAsTouched()\"\r\n readonly\r\n [value]=\"getDisplayValue()\"\r\n [placeholder]=\"placeholder\"\r\n [attr.disabled]=\"disabled ? true : null\"\r\n [class.hasError]=\"hasError\"\r\n class=\"calendar-input\">\r\n <!-- *ngIf=\"!getDisplayValue()\" -->\r\n\r\n <span class=\"calendar-icon\" >\r\n <img alt=\"calendar\" class=\"calendar-icon-img\" [src]='brickclayIcons.calenderIcon'/>\r\n </span>\r\n <button type=\"button\" class=\"clear-btn\" *ngIf=\"getDisplayValue() && isDisplayCrossIcon && !disabled\" (click)=\"clear(); $event.stopPropagation()\" title=\"Clear\">\u00D7</button>\r\n </div>\r\n\r\n <!-- Calendar Popup / Inline -->\r\n <div #calendarPopup\r\n class=\"calendar-popup\"\r\n [class.inline-calendar]=\"inline\"\r\n [class.append-to-body]=\"appendToBody && !inline\"\r\n [style.position]=\"appendToBody && !inline ? 'fixed' : null\"\r\n [style.top]=\"appendToBody && !inline && !popupPlacementAbove ? dropdownStyle.top : null\"\r\n [style.bottom]=\"appendToBody && !inline && popupPlacementAbove ? dropdownStyle.bottom : null\"\r\n [style.left]=\"appendToBody && !inline ? dropdownStyle.left : null\"\r\n tabindex=\"0\"\r\n (keydown)=\"onCalendarPopupKeydown($event)\"\r\n [ngClass]=\"{\r\n 'position-right': !inline && !appendToBody && opens === 'right',\r\n 'position-center': !inline && !appendToBody && opens === 'center',\r\n 'drop-up': !inline && popupPlacementAbove,\r\n 'has-ranges': showRanges && customRanges,\r\n 'dual-calendar-mode': dualCalendar,\r\n 'compact': compact\r\n }\"\r\n *ngIf=\"inline || show\">\r\n\r\n <!-- RANGES -->\r\n <div class=\"ranges\" *ngIf=\"showRanges && customRanges\" role=\"listbox\" aria-label=\"Date ranges\">\r\n <button\r\n type=\"button\"\r\n *ngFor=\"let rangeKey of rangeOrder\"\r\n (click)=\"chooseRange(rangeKey)\"\r\n (keydown)=\"onRangeButtonKeydown($event, rangeKey)\"\r\n [class.active]=\"activeRange === rangeKey\"\r\n [class.custom-range]=\"rangeKey === 'Custom Range'\"\r\n class=\"range-btn\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"activeRange === rangeKey\">\r\n {{ rangeKey }}\r\n </button>\r\n </div>\r\n<div class=\"\" [ngClass]=\"showRanges ? 'w-100 flex-grow-1 border-l border-[#eee]' : ''\">\r\n\r\n\r\n <!-- SINGLE CALENDAR -->\r\n <div *ngIf=\"!dualCalendar\" class=\"calendar-wrapper\">\r\n <div class=\"header\">\r\n <!-- <button (click)=\"prevMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-left-gray.svg\" alt=\"arrow-left\" class=\"arrow-left\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"prevMonth()\" matTooltip=\"Prev month\"\r\n >\r\n <img alt=\"prev\" class=\"h-3 w-3\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(month) }} {{ year }}</span>\r\n <!-- <button (click)=\"nextMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-right-gray.svg\" alt=\"arrow-right\" class=\"arrow-right\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"nextMonth()\" matTooltip=\"Next month\"\r\n >\r\n <img alt=\"next\" class=\"h-3 w-3\" [src]='brickclayIcons.arrowRight'/>\r\n <!--<img src=\"assets/calender/pagination-right-gray.svg\" alt=\"next\" class=\"h-3 w-3\" /> -->\r\n </button>\r\n </div>\r\n\r\n <table class=\"calendar-table\" role=\"grid\" [attr.aria-label]=\"getMonthName(month) + ' ' + year\">\r\n <thead>\r\n <tr role=\"row\">\r\n <th *ngFor=\"let d of resolvedWeekDayLabels\" class=\"weekday-header\" scope=\"col\" role=\"columnheader\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of calendar\" role=\"row\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n role=\"gridcell\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && selectDate(dayObj.day)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(year, month, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(year, month, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(year, month, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(year, month, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(year, month, dayObj.day)\"\r\n [class.calendar-day-keyboard-focus]=\"dayObj.currentMonth && isKeyboardFocusedCell(year, month, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Single Calendar Time Picker -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"single-time\"\r\n [variation]=\"compact ? 'default' : 'lg'\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"singleTimeModel\"\r\n (ngModelChange)=\"onSingleTimePickerChange($event); singleTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('single-time')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- DUAL CALENDAR -->\r\n <div class=\"dual-calendar\" *ngIf=\"dualCalendar\">\r\n <!-- LEFT CALENDAR -->\r\n <div class=\"calendar-left\">\r\n <div class=\"header\">\r\n <button (click)=\"prevLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(leftMonth) }} {{ leftYear }}</span>\r\n <button (click)=\"nextLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\" role=\"grid\" [attr.aria-label]=\"getMonthName(leftMonth) + ' ' + leftYear\">\r\n <thead>\r\n <tr role=\"row\">\r\n <th *ngFor=\"let d of resolvedWeekDayLabels\" class=\"weekday-header\" scope=\"col\" role=\"columnheader\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of leftCalendar\" role=\"row\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n role=\"gridcell\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && selectDate(dayObj.day, false)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(leftYear, leftMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(leftYear, leftMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(leftYear, leftMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(leftYear, leftMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(leftYear, leftMonth, dayObj.day)\"\r\n [class.calendar-day-keyboard-focus]=\"dayObj.currentMonth && isKeyboardFocusedCell(leftYear, leftMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Start Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Start Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-start\"\r\n [variation]=\"compact ? 'default' : 'lg'\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"startTimeModel\"\r\n (ngModelChange)=\"onDualTimePickerChange($event, true); startTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('dual-start')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT CALENDAR -->\r\n <div class=\"calendar-right\">\r\n <div class=\"header\">\r\n <button (click)=\"prevRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(rightMonth) }} {{ rightYear }}</span>\r\n <button (click)=\"nextRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\" role=\"grid\" [attr.aria-label]=\"getMonthName(rightMonth) + ' ' + rightYear\">\r\n <thead>\r\n <tr role=\"row\">\r\n <th *ngFor=\"let d of resolvedWeekDayLabels\" class=\"weekday-header\" scope=\"col\" role=\"columnheader\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of rightCalendar\" role=\"row\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n role=\"gridcell\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && selectDate(dayObj.day, true)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && onDateHover(dayObj.day, true)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(rightYear, rightMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(rightYear, rightMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(rightYear, rightMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(rightYear, rightMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(rightYear, rightMonth, dayObj.day)\"\r\n [class.calendar-day-keyboard-focus]=\"dayObj.currentMonth && isKeyboardFocusedCell(rightYear, rightMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- End Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">End Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-end\"\r\n [variation]=\"compact ? 'default' : 'lg'\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"endTimeModel\"\r\n (ngModelChange)=\"onDualTimePickerChange($event, false); endTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('dual-end')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"footer\" *ngIf=\"!inline && showCancelApply\">\r\n <button *ngIf=\"showCancel\" (click)=\"cancel()\" class=\"btn-cancel\" type=\"button\">Cancel</button>\r\n <button (click)=\"apply()\" class=\"btn-apply\" type=\"button\" [disabled]=\"disabled || isDualRangeApplyBlocked\">Apply</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n</div>\r\n\r\n@if (hasError){\r\n<p class=\"calender-error\">{{errorMessage}}</p>\r\n}\r\n", styles: [".calendar-container,.calendar-container *{font-family:Inter,sans-serif!important}.calendar-container{position:relative;display:inline-block;width:100%}.input-wrapper{position:relative;display:flex;align-items:center}.calendar-input{width:100%;padding:9px 14px 9px 40px;border:1px solid #ddd;border-radius:8px;font-size:14px;cursor:pointer;background:#fff;transition:all .2s}.calendar-input:hover{border-color:#999}.calendar-input:focus{outline:none;border-color:#999}.calendar-icon{position:absolute;left:12px;pointer-events:none;font-size:18px}.clear-btn{position:absolute;right:9px;background:none;border:none;font-size:20px;color:#999;cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;line-height:1;transition:color .2s;top:8px}.clear-btn:hover{color:#333}.calendar-popup{position:absolute;top:110%;left:0;width:320px;background:#fff;border-radius:12px;box-shadow:0 10px 40px #00000026;z-index:1000;animation:slideDown .2s ease-out}.calendar-popup:focus-visible{outline:0!important}.calendar-popup.append-to-body{font-family:Inter,sans-serif;z-index:100000}.calendar-popup.inline-calendar{position:relative;top:0;left:0;width:100%;margin-top:0;animation:none;box-shadow:0 2px 8px #0000001a}.calendar-container.inline-mode{display:block;width:100%}.calendar-popup.dual-calendar-mode{width:600px}.calendar-popup.dual-calendar-mode.has-ranges{width:730px}.calendar-popup.has-ranges{width:450px}.calendar-popup.drop-up{top:auto;bottom:110%;animation:slideUp .2s ease-out}.calendar-popup.position-right{left:auto;right:0}.calendar-popup.position-center{left:50%;transform:translate(-50%)}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ranges{display:flex;flex-direction:column;gap:4px;margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid #eee;min-width:150px;padding-right:8px}.range-btn{padding:7px 10px;border:1px solid transparent;background:transparent;border-radius:4px;cursor:pointer;text-align:left;font-size:14px;transition:all .2s;color:#838383;font-weight:500}.range-btn:hover{background:#f5f5f5;color:#000}.range-btn.active{background:#f0f0f0;color:#000;font-weight:500}.calendar-wrapper{padding:0 12px 12px}.header{display:flex;justify-content:space-between;align-items:center;padding:12px 0}.month-year{font-size:15px;font-weight:500;color:#333;flex:1;text-align:center;text-transform:capitalize}.nav-btn{background:none;border:none;font-size:24px;cursor:pointer;padding:11.5px 14px;color:#666;border-radius:4px;transition:all .2s;line-height:1;height:30px;width:30px;display:flex;justify-content:center;align-items:center}.nav-btn:hover{background:#f0f0f0;color:#000}.nav-btn img{width:auto;max-width:none!important}.calendar-table{width:100%;border-collapse:collapse;text-align:center}.weekday-header{font-size:12px;color:#7e7e7e;font-weight:600;padding:8px 4px;letter-spacing:.3px}.calendar-day{padding:8px 4px;font-size:14px;cursor:pointer;border-radius:6px;transition:all .2s;position:relative;color:#333;font-weight:500;line-height:1.5}.calendar-day:hover:not(.disabled):not(.other-month){background:#efefef;color:#000}.calendar-day.other-month{color:#ccc;cursor:default}.calendar-day.disabled{color:#ddd;cursor:not-allowed;opacity:.5}.calendar-day.active{background:#000!important;color:#fff!important;font-weight:600}.calendar-day.today{font-weight:600}.calendar-day.today:not(.active){background:#e5e4e4}.calendar-day.active:hover{background:#000!important}.calendar-day.in-range{background:#f5f5f5;color:#333;border-radius:0;position:relative}.calendar-day.in-range:hover{background:#e8e8e8}.calendar-day.in-range:before{content:\"\";position:absolute;inset:0;background:#f5f5f5;z-index:-1}.calendar-day.in-range:hover:before{background:#e8e8e8}.calendar-day.multi-selected{background:#4caf50;color:#fff;font-weight:600;border-radius:6px}.calendar-day.multi-selected:hover{background:#45a049}.dual-calendar{display:flex;width:100%}.calendar-left,.calendar-right{flex:1;min-width:0;padding:0 12px 12px}.calendar-popup.has-ranges{display:flex;flex-direction:row}.calendar-popup.has-ranges .ranges{margin-bottom:0;border-bottom:none;padding:10px}.calendar-popup.has-ranges .dual-calendar,.calendar-popup.has-ranges .calendar-wrapper{flex:1}.calendar-right .header{justify-content:space-between}.calendar-right .header .month-year{text-align:center;flex:1}.timepicker-section{margin-top:12px;padding-top:12px;border-top:1px solid #eee}.timepicker-label{font-size:12px;font-weight:500;color:#000;margin-bottom:4px;letter-spacing:-.28px}.custom-time-picker{display:flex;flex-direction:column;gap:8px;align-items:start}.time-input-group{display:flex;align-items:center;justify-content:center;gap:8px;background:#f8f9fa;padding:12px;border-radius:8px;border:1px solid #e0e0e0}.time-control{display:flex;flex-direction:column;align-items:center}.time-btn{background:#fff;border:1px solid #ddd;width:28px;height:20px;cursor:pointer;font-size:10px;color:#666;border-radius:4px;transition:all .2s;display:flex;align-items:center;justify-content:center;padding:0;line-height:1}.time-btn:hover{background:#e4e4e4;color:#fff;border-color:#e4e4e4}.time-btn.up{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:none}.time-btn.down{border-top-left-radius:0;border-top-right-radius:0;border-top:none}.time-input{width:40px;height:32px;text-align:center;border:1px solid #ddd;border-radius:4px;font-size:16px;font-weight:600;background:#fff;color:#333}.time-separator{font-size:18px;font-weight:600;color:#666;margin:0 2px}.ampm-control{display:flex;flex-direction:column;gap:4px;margin-left:8px}.ampm-btn{padding:6px 12px;border:1px solid #ddd;background:#fff;border-radius:4px;cursor:pointer;font-size:12px;font-weight:600;color:#666;transition:all .2s;min-width:45px}.ampm-btn:hover{background:#f0f0f0}.ampm-btn.active{background:#000;color:#fff;border-color:#000}.html5-time-input{margin-top:8px;padding:8px;border:1px solid #ddd;border-radius:6px;font-size:14px;width:100%;max-width:120px}.footer{padding:12px;display:flex;justify-content:flex-end;gap:8px;border-top:1px solid #eee}.btn-cancel,.btn-apply{padding:8px 16px;border:none;border-radius:4px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;min-width:80px}.btn-cancel{background:#fff;color:#666;border:1px solid #ddd}.btn-apply{background:#000;color:#fff}.btn-apply:active{transform:translateY(0)}@media (max-width: 768px){.calendar-popup{width:100%;max-width:320px;max-height:300px;overflow:auto}.calendar-popup.dual-calendar-mode{width:100%;max-width:100%}.calendar-popup.has-ranges{flex-direction:column}.calendar-popup.has-ranges .ranges{border-right:none;border-bottom:1px solid #eee;padding-right:0;margin-right:0;padding-bottom:16px;margin-bottom:16px}.dual-calendar{flex-direction:column}.time-input-group{flex-wrap:wrap;justify-content:center}}.ranges::-webkit-scrollbar{width:6px}.ranges::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.ranges::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.ranges::-webkit-scrollbar-thumb:hover{background:#555}.w-100{width:100%}.flex-grow-1{flex-grow:1}.calendar-input.calendar-input-has-error{@apply border-[#d11e14];}.calendar-input:disabled{cursor:not-allowed;border-color:#e3e3e7;background-color:#f4f4f6;color:#a1a3ae}.btn-apply:disabled{cursor:not-allowed!important;opacity:.7}.calendar-day.calendar-day-keyboard-focus:not(.disabled):not(.other-month){outline:0px solid #000}.calendar-popup.compact{width:240px}.calendar-popup.compact.has-ranges{width:380px}.calendar-popup.compact.dual-calendar-mode{width:480px}.calendar-popup.compact.dual-calendar-mode.has-ranges{width:600px}.calendar-popup.compact .header{padding:8px 0}.calendar-popup.compact .month-year{font-size:13px}.calendar-popup.compact .nav-btn{height:24px;width:24px;padding:6px 8px}.calendar-popup.compact .calendar-wrapper,.calendar-popup.compact .calendar-left,.calendar-popup.compact .calendar-right{padding:0 8px 8px}.calendar-popup.compact .weekday-header{font-size:11px;padding:4px 2px}.calendar-popup.compact .calendar-day{font-size:12px;padding:5px 2px;line-height:1.3}.calendar-popup.compact .ranges{min-width:120px;gap:2px;margin-bottom:8px;padding-bottom:8px}.calendar-popup.compact.has-ranges .ranges{padding:6px}.calendar-popup.compact .range-btn{font-size:12px;padding:5px 8px}.calendar-popup.compact .timepicker-section{margin-top:8px;padding-top:8px}.calendar-popup.compact .timepicker-label{font-size:11px}.calendar-popup.compact .footer{padding:8px;gap:6px}.calendar-popup.compact .btn-cancel,.calendar-popup.compact .btn-apply{font-size:11px;padding:6px 12px;min-width:64px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BkTimePicker, selector: "bk-time-picker", inputs: ["required", "value", "label", "placeholder", "clearable", "position", "variation", "pickerId", "closePicker", "timeFormat", "showSeconds", "autoPosition", "appendToBody", "disabled"], outputs: ["change", "timeChange", "pickerOpened", "pickerClosed"] }] });
|
|
3059
|
+
], viewQueries: [{ propertyName: "inputWrapper", first: true, predicate: ["inputWrapper"], descendants: true }, { propertyName: "calendarPopupRef", first: true, predicate: ["calendarPopup"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"calendar-container relative\" [class.open]=\"show\" [class.inline-mode]=\"inline\" [class.disabled]=\"disabled\">\r\n <!-- Input field -->\r\n <div #inputWrapper class=\"input-wrapper\" *ngIf=\"!inline\">\r\n <input\r\n type=\"text\"\r\n (click)=\"!disabled && toggle()\"\r\n (keydown.enter)=\"$event.preventDefault()\"\r\n (blur)=\"markAsTouched()\"\r\n readonly\r\n [value]=\"getDisplayValue()\"\r\n [placeholder]=\"placeholder\"\r\n [attr.disabled]=\"disabled ? true : null\"\r\n [class.hasError]=\"hasError\"\r\n class=\"calendar-input\">\r\n <!-- *ngIf=\"!getDisplayValue()\" -->\r\n\r\n <span class=\"calendar-icon\" >\r\n <img alt=\"calendar\" class=\"calendar-icon-img\" [src]='brickclayIcons.calenderIcon'/>\r\n </span>\r\n <button type=\"button\" class=\"clear-btn\" *ngIf=\"getDisplayValue() && isDisplayCrossIcon && !disabled\" (click)=\"clear(); $event.stopPropagation()\" title=\"Clear\">\u00D7</button>\r\n </div>\r\n\r\n <!-- Calendar Popup / Inline -->\r\n <div #calendarPopup\r\n class=\"calendar-popup\"\r\n [class.inline-calendar]=\"inline\"\r\n [class.append-to-body]=\"appendToBody && !inline\"\r\n [style.position]=\"appendToBody && !inline ? 'fixed' : null\"\r\n [style.top]=\"appendToBody && !inline && !popupPlacementAbove ? dropdownStyle.top : null\"\r\n [style.bottom]=\"appendToBody && !inline && popupPlacementAbove ? dropdownStyle.bottom : null\"\r\n [style.left]=\"appendToBody && !inline ? dropdownStyle.left : null\"\r\n tabindex=\"0\"\r\n (keydown)=\"onCalendarPopupKeydown($event)\"\r\n [ngClass]=\"{\r\n 'position-right': !inline && !appendToBody && opens === 'right',\r\n 'position-center': !inline && !appendToBody && opens === 'center',\r\n 'drop-up': !inline && popupPlacementAbove,\r\n 'has-ranges': showRanges && customRanges,\r\n 'dual-calendar-mode': dualCalendar,\r\n 'compact': compact\r\n }\"\r\n *ngIf=\"inline || show\">\r\n\r\n <!-- RANGES -->\r\n <div class=\"ranges\" *ngIf=\"showRanges && customRanges\" role=\"listbox\" aria-label=\"Date ranges\">\r\n <button\r\n type=\"button\"\r\n *ngFor=\"let rangeKey of rangeOrder\"\r\n (click)=\"chooseRange(rangeKey)\"\r\n (keydown)=\"onRangeButtonKeydown($event, rangeKey)\"\r\n [class.active]=\"activeRange === rangeKey\"\r\n [class.custom-range]=\"rangeKey === 'Custom Range'\"\r\n class=\"range-btn\"\r\n role=\"option\"\r\n [attr.aria-selected]=\"activeRange === rangeKey\">\r\n {{ rangeKey }}\r\n </button>\r\n </div>\r\n<div class=\"\" [ngClass]=\"showRanges ? 'w-100 flex-grow-1 border-l border-[#eee]' : ''\">\r\n\r\n\r\n <!-- SINGLE CALENDAR -->\r\n <div *ngIf=\"!dualCalendar\" class=\"calendar-wrapper\">\r\n <div class=\"header\">\r\n <!-- <button (click)=\"prevMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-left-gray.svg\" alt=\"arrow-left\" class=\"arrow-left\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"prevMonth()\" matTooltip=\"Prev month\"\r\n >\r\n <img alt=\"prev\" class=\"h-3 w-3\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(month) }} {{ year }}</span>\r\n <!-- <button (click)=\"nextMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-right-gray.svg\" alt=\"arrow-right\" class=\"arrow-right\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"nextMonth()\" matTooltip=\"Next month\"\r\n >\r\n <img alt=\"next\" class=\"h-3 w-3\" [src]='brickclayIcons.arrowRight'/>\r\n <!--<img src=\"assets/calender/pagination-right-gray.svg\" alt=\"next\" class=\"h-3 w-3\" /> -->\r\n </button>\r\n </div>\r\n\r\n <table class=\"calendar-table\" role=\"grid\" [attr.aria-label]=\"getMonthName(month) + ' ' + year\">\r\n <thead>\r\n <tr role=\"row\">\r\n <th *ngFor=\"let d of resolvedWeekDayLabels\" class=\"weekday-header\" scope=\"col\" role=\"columnheader\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of calendar\" role=\"row\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n role=\"gridcell\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && selectDate(dayObj.day)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(year, month, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(year, month, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(year, month, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(year, month, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(year, month, dayObj.day)\"\r\n [class.calendar-day-keyboard-focus]=\"dayObj.currentMonth && isKeyboardFocusedCell(year, month, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Single Calendar Time Picker -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"single-time\"\r\n [variation]=\"compact ? 'default' : 'lg'\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"singleTimeModel\"\r\n (ngModelChange)=\"onSingleTimePickerChange($event); singleTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('single-time')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- DUAL CALENDAR -->\r\n <div class=\"dual-calendar\" *ngIf=\"dualCalendar\">\r\n <!-- LEFT CALENDAR -->\r\n <div class=\"calendar-left\">\r\n <div class=\"header\">\r\n <button (click)=\"prevLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(leftMonth) }} {{ leftYear }}</span>\r\n <button (click)=\"nextLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\" role=\"grid\" [attr.aria-label]=\"getMonthName(leftMonth) + ' ' + leftYear\">\r\n <thead>\r\n <tr role=\"row\">\r\n <th *ngFor=\"let d of resolvedWeekDayLabels\" class=\"weekday-header\" scope=\"col\" role=\"columnheader\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of leftCalendar\" role=\"row\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n role=\"gridcell\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && selectDate(dayObj.day, false)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(leftYear, leftMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(leftYear, leftMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(leftYear, leftMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(leftYear, leftMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(leftYear, leftMonth, dayObj.day)\"\r\n [class.calendar-day-keyboard-focus]=\"dayObj.currentMonth && isKeyboardFocusedCell(leftYear, leftMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Start Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Start Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-start\"\r\n [variation]=\"compact ? 'default' : 'lg'\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"startTimeModel\"\r\n (ngModelChange)=\"onDualTimePickerChange($event, true); startTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('dual-start')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT CALENDAR -->\r\n <div class=\"calendar-right\">\r\n <div class=\"header\">\r\n <button (click)=\"prevRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(rightMonth) }} {{ rightYear }}</span>\r\n <button (click)=\"nextRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\" role=\"grid\" [attr.aria-label]=\"getMonthName(rightMonth) + ' ' + rightYear\">\r\n <thead>\r\n <tr role=\"row\">\r\n <th *ngFor=\"let d of resolvedWeekDayLabels\" class=\"weekday-header\" scope=\"col\" role=\"columnheader\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of rightCalendar\" role=\"row\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n role=\"gridcell\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && selectDate(dayObj.day, true)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && onDateHover(dayObj.day, true)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(rightYear, rightMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(rightYear, rightMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(rightYear, rightMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(rightYear, rightMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(rightYear, rightMonth, dayObj.day)\"\r\n [class.calendar-day-keyboard-focus]=\"dayObj.currentMonth && isKeyboardFocusedCell(rightYear, rightMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- End Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">End Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-end\"\r\n [variation]=\"compact ? 'default' : 'lg'\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"endTimeModel\"\r\n (ngModelChange)=\"onDualTimePickerChange($event, false); endTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('dual-end')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"footer\" *ngIf=\"!inline && showCancelApply\">\r\n <button *ngIf=\"showCancel\" (click)=\"cancel()\" class=\"btn-cancel\" type=\"button\">Cancel</button>\r\n <button (click)=\"apply()\" class=\"btn-apply\" type=\"button\" [disabled]=\"disabled || isDualRangeApplyBlocked\">Apply</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n</div>\r\n\r\n@if (hasError){\r\n<p class=\"calender-error\">{{errorMessage}}</p>\r\n}\r\n", styles: [".calendar-container,.calendar-container *{font-family:Inter,sans-serif!important}.calendar-container{position:relative;display:inline-block;width:100%}.input-wrapper{position:relative;display:flex;align-items:center}.calendar-input{width:100%;padding:9px 14px 9px 40px;border:1px solid #ddd;border-radius:8px;font-size:14px;cursor:pointer;background:#fff;transition:all .2s}.calendar-input:hover{border-color:#999}.calendar-input:focus{outline:none;border-color:#999}.calendar-icon{position:absolute;left:12px;pointer-events:none;font-size:18px}.clear-btn{position:absolute;right:9px;background:none;border:none;font-size:20px;color:#999;cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;line-height:1;transition:color .2s;top:8px}.clear-btn:hover{color:#333}.calendar-popup{position:absolute;top:110%;left:0;width:320px;background:#fff;border-radius:12px;box-shadow:0 10px 40px #00000026;z-index:1000;animation:slideDown .2s ease-out}.calendar-popup:focus-visible{outline:0!important}.calendar-popup.append-to-body{font-family:Inter,sans-serif;z-index:100000}.calendar-popup.inline-calendar{position:relative;top:0;left:0;width:100%;margin-top:0;animation:none;box-shadow:0 2px 8px #0000001a}.calendar-container.inline-mode{display:block;width:100%}.calendar-popup.dual-calendar-mode{width:600px}.calendar-popup.dual-calendar-mode.has-ranges{width:730px}.calendar-popup.has-ranges{width:450px}.calendar-popup.drop-up{top:auto;bottom:110%;animation:slideUp .2s ease-out}.calendar-popup.position-right{left:auto;right:0}.calendar-popup.position-center{left:50%;transform:translate(-50%)}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ranges{display:flex;flex-direction:column;gap:4px;margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid #eee;min-width:150px;padding-right:8px}.range-btn{padding:7px 10px;border:1px solid transparent;background:transparent;border-radius:4px;cursor:pointer;text-align:left;font-size:14px;transition:all .2s;color:#838383;font-weight:500}.range-btn:hover{background:#f5f5f5;color:#000}.range-btn.active{background:#f0f0f0;color:#000;font-weight:500}.calendar-wrapper{padding:0 12px 12px}.header{display:flex;justify-content:space-between;align-items:center;padding:12px 0}.month-year{font-size:15px;font-weight:500;color:#333;flex:1;text-align:center;text-transform:capitalize}.nav-btn{background:none;border:none;font-size:24px;cursor:pointer;padding:11.5px 14px;color:#666;border-radius:4px;transition:all .2s;line-height:1;height:30px;width:30px;display:flex;justify-content:center;align-items:center}.nav-btn:hover{background:#f0f0f0;color:#000}.nav-btn img{width:auto;max-width:none!important}.calendar-table{width:100%;border-collapse:collapse;text-align:center}.weekday-header{font-size:12px;color:#7e7e7e;font-weight:600;padding:8px 4px;letter-spacing:.3px}.calendar-day{padding:8px 4px;font-size:14px;cursor:pointer;border-radius:6px;transition:all .2s;position:relative;color:#333;font-weight:500;line-height:1.5}.calendar-day:hover:not(.disabled):not(.other-month){background:#efefef;color:#000}.calendar-day.other-month{color:#ccc;cursor:default}.calendar-day.disabled{color:#ddd;cursor:not-allowed;opacity:.5}.calendar-day.active{background:#000!important;color:#fff!important;font-weight:600}.calendar-day.today{font-weight:600}.calendar-day.today:not(.active){background:#e5e4e4}.calendar-day.active:hover{background:#000!important}.calendar-day.in-range{background:#f5f5f5;color:#333;border-radius:0;position:relative}.calendar-day.in-range:hover{background:#e8e8e8}.calendar-day.in-range:before{content:\"\";position:absolute;inset:0;background:#f5f5f5;z-index:-1}.calendar-day.in-range:hover:before{background:#e8e8e8}.calendar-day.multi-selected{background:#4caf50;color:#fff;font-weight:600;border-radius:6px}.calendar-day.multi-selected:hover{background:#45a049}.dual-calendar{display:flex;width:100%}.calendar-left,.calendar-right{flex:1;min-width:0;padding:0 12px 12px}.calendar-popup.has-ranges{display:flex;flex-direction:row}.calendar-popup.has-ranges .ranges{margin-bottom:0;border-bottom:none;padding:10px}.calendar-popup.has-ranges .dual-calendar,.calendar-popup.has-ranges .calendar-wrapper{flex:1}.calendar-right .header{justify-content:space-between}.calendar-right .header .month-year{text-align:center;flex:1}.timepicker-section{margin-top:12px;padding-top:12px;border-top:1px solid #eee}.timepicker-label{font-size:12px;font-weight:500;color:#000;margin-bottom:4px;letter-spacing:-.28px}.custom-time-picker{display:flex;flex-direction:column;gap:8px;align-items:start}.time-input-group{display:flex;align-items:center;justify-content:center;gap:8px;background:#f8f9fa;padding:12px;border-radius:8px;border:1px solid #e0e0e0}.time-control{display:flex;flex-direction:column;align-items:center}.time-btn{background:#fff;border:1px solid #ddd;width:28px;height:20px;cursor:pointer;font-size:10px;color:#666;border-radius:4px;transition:all .2s;display:flex;align-items:center;justify-content:center;padding:0;line-height:1}.time-btn:hover{background:#e4e4e4;color:#fff;border-color:#e4e4e4}.time-btn.up{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:none}.time-btn.down{border-top-left-radius:0;border-top-right-radius:0;border-top:none}.time-input{width:40px;height:32px;text-align:center;border:1px solid #ddd;border-radius:4px;font-size:16px;font-weight:600;background:#fff;color:#333}.time-separator{font-size:18px;font-weight:600;color:#666;margin:0 2px}.ampm-control{display:flex;flex-direction:column;gap:4px;margin-left:8px}.ampm-btn{padding:6px 12px;border:1px solid #ddd;background:#fff;border-radius:4px;cursor:pointer;font-size:12px;font-weight:600;color:#666;transition:all .2s;min-width:45px}.ampm-btn:hover{background:#f0f0f0}.ampm-btn.active{background:#000;color:#fff;border-color:#000}.html5-time-input{margin-top:8px;padding:8px;border:1px solid #ddd;border-radius:6px;font-size:14px;width:100%;max-width:120px}.footer{padding:12px;display:flex;justify-content:flex-end;gap:8px;border-top:1px solid #eee}.btn-cancel,.btn-apply{padding:8px 16px;border:none;border-radius:4px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;min-width:80px}.btn-cancel{background:#fff;color:#666;border:1px solid #ddd}.btn-apply{background:#000;color:#fff}.btn-apply:active{transform:translateY(0)}@media (max-width: 768px){.calendar-popup{width:100%;max-width:320px;max-height:300px;overflow:auto}.calendar-popup.dual-calendar-mode{width:100%;max-width:100%}.calendar-popup.has-ranges{flex-direction:column}.calendar-popup.has-ranges .ranges{border-right:none;border-bottom:1px solid #eee;padding-right:0;margin-right:0;padding-bottom:16px;margin-bottom:16px}.dual-calendar{flex-direction:column}.time-input-group{flex-wrap:wrap;justify-content:center}}.ranges::-webkit-scrollbar{width:6px}.ranges::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.ranges::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.ranges::-webkit-scrollbar-thumb:hover{background:#555}.w-100{width:100%}.flex-grow-1{flex-grow:1}.calendar-input.calendar-input-has-error{@apply border-[#d11e14];}.calendar-input:disabled{cursor:not-allowed;border-color:#e3e3e7;background-color:#f4f4f6;color:#a1a3ae}.btn-apply:disabled{cursor:not-allowed!important;opacity:.7}.calendar-day.calendar-day-keyboard-focus:not(.disabled):not(.other-month){outline:0px solid #000}.calendar-popup.compact{width:240px}.calendar-popup.compact.has-ranges{width:380px}.calendar-popup.compact.dual-calendar-mode{width:480px}.calendar-popup.compact.dual-calendar-mode.has-ranges{width:600px}.calendar-popup.compact .header{padding:8px 0}.calendar-popup.compact .month-year{font-size:13px}.calendar-popup.compact .nav-btn{height:24px;width:24px;padding:6px 8px}.calendar-popup.compact .calendar-wrapper,.calendar-popup.compact .calendar-left,.calendar-popup.compact .calendar-right{padding:0 8px 8px}.calendar-popup.compact .weekday-header{font-size:11px;padding:4px 2px}.calendar-popup.compact .calendar-day{font-size:12px;padding:5px 2px;line-height:1.3}.calendar-popup.compact .ranges{min-width:120px;gap:2px;margin-bottom:8px;padding-bottom:8px}.calendar-popup.compact.has-ranges .ranges{padding:6px}.calendar-popup.compact .range-btn{font-size:12px;padding:5px 8px}.calendar-popup.compact .timepicker-section{margin-top:8px;padding-top:8px}.calendar-popup.compact .timepicker-label{font-size:11px}.calendar-popup.compact .footer{padding:8px;gap:6px}.calendar-popup.compact .btn-cancel,.calendar-popup.compact .btn-apply{font-size:11px;padding:6px 12px;min-width:64px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BkTimePicker, selector: "bk-time-picker", inputs: ["required", "value", "label", "placeholder", "clearable", "position", "variation", "pickerId", "closePicker", "timeFormat", "showSeconds", "autoPosition", "appendToBody", "disabled"], outputs: ["change", "timeChange", "pickerOpened", "pickerClosed"] }] });
|
|
3060
3060
|
}
|
|
3061
3061
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkCustomCalendar, decorators: [{
|
|
3062
3062
|
type: Component,
|
|
@@ -4117,13 +4117,13 @@ class BkTextarea {
|
|
|
4117
4117
|
registerOnTouched(fn) {
|
|
4118
4118
|
this.onTouched = fn;
|
|
4119
4119
|
}
|
|
4120
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkTextarea, deps: [{ token:
|
|
4120
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkTextarea, deps: [{ token: i2.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
4121
4121
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkTextarea, isStandalone: true, selector: "bk-textarea", inputs: { autoComplete: "autoComplete", name: "name", id: "id", label: "label", placeholder: "placeholder", rows: "rows", hint: "hint", required: "required", maxlength: "maxlength", minlength: "minlength", hasError: "hasError", disabled: "disabled", errorMessage: "errorMessage", tabIndex: "tabIndex", readOnly: "readOnly", autoCapitalize: "autoCapitalize", inputMode: "inputMode" }, outputs: { input: "input", change: "change", blur: "blur", focus: "focus" }, ngImport: i0, template: "<div class=\"flex flex-col gap-1.5 w-full\">\r\n @if (label) {\r\n <label class=\"text-sm font-medium text-[#141414] block\" [for]=\"id\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"text-[#E7000B] ml-0.5\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"relative\">\r\n <textarea\r\n [id]=\"id\"\r\n [name]=\"name\"\r\n [disabled]=\"disabled\"\r\n [tabindex]=\"tabIndex\"\r\n [readOnly]=\"readOnly\"\r\n [attr.maxlength]=\"maxlength\"\r\n [attr.minlength]=\"minlength\"\r\n [autocomplete]=\"autoComplete\"\r\n [autocapitalize]=\"autoCapitalize\"\r\n [inputMode]=\"inputMode\"\r\n [value]=\"value\"\r\n (input)=\"handleInput($event)\"\r\n (change)=\"handleChange($event)\"\r\n (blur)=\"handleBlur($event)\"\r\n (focus)=\"handleFocus($event)\"\r\n [placeholder]=\"placeholder\"\r\n [autocomplete]=\"autoComplete\"\r\n rows=\"{{ rows }}\"\r\n class=\"w-full px-3 py-2.5 text-sm border border-[#E3E3E7] outline-none transition-colors duration-200 bg-white resize-y placeholder:text-[#6B7080] rounded bk-textarea-shadow \"\r\n [ngClass]=\"{\r\n 'border-[#FA727A]': hasError && !disabled,\r\n 'focus:border-[#6B7080]': !hasError && !disabled,\r\n '!bg-[#F4F4F6] !text-[#A1A3AE] cursor-not-allowed !border-[#E3E3E7]': disabled,\r\n }\"\r\n ></textarea>\r\n </div>\r\n\r\n <div class=\"flex justify-between items-start font-normal text-sm\">\r\n <div class=\"flex-1\">\r\n @if (hasError) {\r\n <span class=\"font-medium text-xs leading-normal text-[#C10007] text-left\">\r\n {{ errorMessage }}\r\n </span>\r\n } @else if (hint) {\r\n <span class=\"text-[#868997]\">\r\n {{ hint }}\r\n </span>\r\n }\r\n </div>\r\n\r\n @if (maxlength) {\r\n <div class=\"text-[#868997] tabular-nums flex-shrink-0\">\r\n {{ value.length }}/{{ maxlength }}\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }] });
|
|
4122
4122
|
}
|
|
4123
4123
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkTextarea, decorators: [{
|
|
4124
4124
|
type: Component,
|
|
4125
4125
|
args: [{ selector: 'bk-textarea', standalone: true, imports: [CommonModule, FormsModule], template: "<div class=\"flex flex-col gap-1.5 w-full\">\r\n @if (label) {\r\n <label class=\"text-sm font-medium text-[#141414] block\" [for]=\"id\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"text-[#E7000B] ml-0.5\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"relative\">\r\n <textarea\r\n [id]=\"id\"\r\n [name]=\"name\"\r\n [disabled]=\"disabled\"\r\n [tabindex]=\"tabIndex\"\r\n [readOnly]=\"readOnly\"\r\n [attr.maxlength]=\"maxlength\"\r\n [attr.minlength]=\"minlength\"\r\n [autocomplete]=\"autoComplete\"\r\n [autocapitalize]=\"autoCapitalize\"\r\n [inputMode]=\"inputMode\"\r\n [value]=\"value\"\r\n (input)=\"handleInput($event)\"\r\n (change)=\"handleChange($event)\"\r\n (blur)=\"handleBlur($event)\"\r\n (focus)=\"handleFocus($event)\"\r\n [placeholder]=\"placeholder\"\r\n [autocomplete]=\"autoComplete\"\r\n rows=\"{{ rows }}\"\r\n class=\"w-full px-3 py-2.5 text-sm border border-[#E3E3E7] outline-none transition-colors duration-200 bg-white resize-y placeholder:text-[#6B7080] rounded bk-textarea-shadow \"\r\n [ngClass]=\"{\r\n 'border-[#FA727A]': hasError && !disabled,\r\n 'focus:border-[#6B7080]': !hasError && !disabled,\r\n '!bg-[#F4F4F6] !text-[#A1A3AE] cursor-not-allowed !border-[#E3E3E7]': disabled,\r\n }\"\r\n ></textarea>\r\n </div>\r\n\r\n <div class=\"flex justify-between items-start font-normal text-sm\">\r\n <div class=\"flex-1\">\r\n @if (hasError) {\r\n <span class=\"font-medium text-xs leading-normal text-[#C10007] text-left\">\r\n {{ errorMessage }}\r\n </span>\r\n } @else if (hint) {\r\n <span class=\"text-[#868997]\">\r\n {{ hint }}\r\n </span>\r\n }\r\n </div>\r\n\r\n @if (maxlength) {\r\n <div class=\"text-[#868997] tabular-nums flex-shrink-0\">\r\n {{ value.length }}/{{ maxlength }}\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n" }]
|
|
4126
|
-
}], ctorParameters: () => [{ type:
|
|
4126
|
+
}], ctorParameters: () => [{ type: i2.NgControl, decorators: [{
|
|
4127
4127
|
type: Optional
|
|
4128
4128
|
}, {
|
|
4129
4129
|
type: Self
|
|
@@ -4819,7 +4819,7 @@ class BkGrid {
|
|
|
4819
4819
|
});
|
|
4820
4820
|
}
|
|
4821
4821
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkGrid, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4822
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkGrid, isStandalone: true, selector: "bk-grid", inputs: { draggable: "draggable", columns: "columns", result: "result", actions: "actions", customClass: "customClass", actionIconClass: "actionIconClass", actionClass: "actionClass", showNoRecords: "showNoRecords", noRecordFoundHeight: "noRecordFoundHeight" }, outputs: { change: "change", actionClick: "actionClick", sortChange: "sortChange", dragDropChange: "dragDropChange" }, viewQueries: [{ propertyName: "tableScrollContainer", first: true, predicate: ["tableScrollContainer"], descendants: true }], ngImport: i0, template: "<div #tableScrollContainer cdkScrollable class=\"overflow-y-auto\" [ngClass]=\"customClass\">\r\n <table class=\"min-w-full text-sm text-left text-gray-800 table-auto border-collapse\">\r\n <!-- ================= HEADER ================= -->\r\n <thead>\r\n <tr>\r\n @for (col of columns; track col.header; let i = $index) {\r\n @if (isColumnVisible(col)) {\r\n <th\r\n class=\"grid-header sticky top-[-1px]\"\r\n [class.cursor-pointer]=\"col.sortable\"\r\n [class.cursor-default]=\"!col.sortable\"\r\n [class.action-sticky]=\"col.sticky\"\r\n [class.z-10]=\"col.sticky\"\r\n class=\"{{ col.headerClass }} {{ col.cellClass }}\"\r\n (click)=\"sort(col, i)\"\r\n >\r\n <!-- [ngClass]=\"col.headerClass\"\r\n [ngClass]=\"col.cellClass\" -->\r\n <span\r\n class=\"flex items-center gap-1\"\r\n [ngClass]=\"\r\n sortColumn === col.field\r\n ? sortDirection === 'asc'\r\n ? 'grid-asc'\r\n : 'grid-desc'\r\n : ''\r\n \"\r\n >\r\n {{ col.header }}\r\n @if (col.sortable) {\r\n <span class=\"grid-sort-icon\"></span>\r\n }\r\n </span>\r\n </th>\r\n }\r\n }\r\n\r\n @if (actions.length) {\r\n <th class=\"grid-header sticky top-0 action-sticky z-10 !bg-[#FBFBFC] w-20 {{actionClass}}\">Action</th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <!-- ================= BODY ================= -->\r\n <tbody\r\n cdkDropList\r\n [cdkDropListDisabled]=\"!draggable\"\r\n [cdkDropListData]=\"result || []\"\r\n (cdkDropListDropped)=\"dropList($event)\"\r\n >\r\n @for (row of result; track row; let rowIndex = $index) {\r\n <tr\r\n cdkDrag\r\n cdkDragLockAxis=\"y\"\r\n [cdkDragDisabled]=\"!draggable\"\r\n (cdkDragStarted)=\"onDragStart($event)\"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n class=\"\"\r\n [ngClass]=\"{ 'cursor-move ': draggable }\"\r\n >\r\n @for (col of columns; track col.header; let colIndex = $index) {\r\n @if (isColumnVisible(col)) {\r\n <td class=\"grid-cell text-nowrap\" [ngClass]=\"col.cellClass\">\r\n @if (draggable && colIndex === firstVisibleColumnIndex) {\r\n <span\r\n cdkDragHandle\r\n class=\"mr-2 text-gray-400\"\r\n [ngClass]=\"{ 'cursor-move': draggable }\"\r\n >\u2630</span\r\n >\r\n }\r\n @if (col.checkbox) {\r\n <bk-checkbox\r\n checkboxClass=\"sm\"\r\n [ngModel]=\"getCheckboxValue(row, col)\"\r\n (ngModelChange)=\"setCheckboxValue(row, col, $event)\"\r\n [disabled]=\"typeof col.checkboxDisabled === 'function' ? col.checkboxDisabled(row) : col.checkboxDisabled || false\"\r\n [bkTooltip]=\"typeof col.checkboxTooltip === 'function' ? col.checkboxTooltip(row) : col.checkboxTooltip || ''\"\r\n [bkTooltipPosition]=\"col.checkboxTooltipPosition || 'top'\"\r\n ></bk-checkbox>\r\n } @else if (col.badges) {\r\n @let badge = getBadge(row, col);\r\n @if (badge) {\r\n <bk-badge\r\n [label]=\"badge.label\"\r\n [variant]=\"badge.variant\"\r\n [size]=\"badge.size\"\r\n [color]=\"badge.color\"\r\n [dot]=\"badge.dot\"\r\n [customClass]=\"badge.customClass\"\r\n [bkTooltip]=\"badge.toolTipLabel || ''\"\r\n [bkTooltipPosition]=\"badge.tooltipPosition || 'top'\"\r\n ></bk-badge>\r\n }\r\n } @else if (col.icons) {\r\n @let iconsList = getIcons(row, col);\r\n <div class=\"flex justify-center items-center gap-2\">\r\n @for (icon of iconsList; track $index) {\r\n @if(icon.url){\r\n <img\r\n [src]=\"icon.url\"\r\n class=\"size-4\"\r\n [ngClass]=\"{ 'cursor-pointer': icon.url }\"\r\n [bkTooltip]=\"icon.toolTipLabel || []\"\r\n [bkTooltipPosition]=\"icon.tooltipPosition || 'top'\"\r\n />\r\n }\r\n }\r\n </div>\r\n } @else if (col.toolTipField) {\r\n <span\r\n [bkTooltip]=\"getTooltipValue(row, col)\"\r\n [bkTooltipPosition]=\"col.toolTipPosition || 'top'\"\r\n >\r\n {{ getCellValue(row, col) }}\r\n </span>\r\n } @else {\r\n {{ getCellValue(row, col) }}\r\n }\r\n </td>\r\n }\r\n }\r\n\r\n @if (getRowActions(row).length) {\r\n <td class=\"grid-cell action-sticky text-center\">\r\n <div class=\"flex items-center justify-center gap-1.5\">\r\n @for (action of getRowActions(row); track action.name) {\r\n @if (isActionVisible(action, row)) {\r\n <button\r\n [bkTooltip]=\"action.tooltip\"\r\n [bkTooltipPosition]=\"action?.tooltipPosition || 'top'\"\r\n class=\"size-6 flex items-center justify-center rounded hover:bg-[#F8F8FA] {{actionIconClass}}\"\r\n (click)=\"emitAction(action, row)\"\r\n [disabled]=\"isActionDisabled(action, row)\"\r\n >\r\n <img [src]=\"action.icon\" width=\"14\" height=\"14\" alt=\"action-icon\" />\r\n </button>\r\n }\r\n }\r\n </div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n @if (showNoRecords) {\r\n <tr>\r\n <td\r\n [attr.colspan]=\"columns.length + (actions.length ? 1 : 0)\"\r\n class=\"text-center py-10 {{ noRecordFoundHeight }}\"\r\n >\r\n <div class=\"flex flex-col justify-center items-center w-full h-auto\">\r\n <img\r\n src=\"./assets/media/logos/no-data-found.jpg\"\r\n class=\"mb-3 w-96\"\r\n alt=\"No data found\"\r\n />\r\n\r\n <span class=\"block text-sm leading-3 text-center font-semibold text-[#60646C] mt-2\"\r\n >Data may be empty, or try adjusting your filter.</span\r\n >\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>\r\n", styles: [".grid-header{@apply bg-[#F9FAFA] text-xs text-[#60646C] font-semibold capitalize px-[17px] py-2.5 whitespace-nowrap;box-shadow:0 1px #ebedf3;-webkit-transform:translateZ(0);transform:translateZ(0);backface-visibility:hidden;-webkit-backface-visibility:hidden}thead tr th:first-child{border-top-left-radius:.75rem}thead tr th:last-child{border-top-right-radius:.75rem}.grid-cell{@apply text-[#15191E] text-[13px] font-medium leading-4 px-4 py-2 border-x border-b border-[#EBEDF3];}.grid-cell:last-child{@apply border-e-0;}.grid-cell:first-child,.grid-first-cell{@apply border-s-0;}.grid-last-cell{@apply border-e-0;}.grid-action-sticky{@apply sticky bg-white right-[.1px] z-[1px];}.grid-action-sticky:before{@apply absolute top-0 bottom-0 left-[-8px] w-2;content:\"\";background-image:linear-gradient(to left,rgba(0,0,0,.05),transparent)}.grid-required{@apply font-medium text-sm leading-normal after:content-[\"*\"] after:text-[#C10007] after:ms-0.5;}.grid-sort{display:inline-flex;align-items:center;gap:.35rem;cursor:pointer;line-height:1}.grid-sort-icon{display:inline-flex;flex-direction:column;justify-content:center;align-items:center;height:.875rem;width:.875rem;gap:.125rem;line-height:1}.grid-sort-icon:before{display:inline-block;content:\"\";height:.3rem;width:.54rem;background-repeat:no-repeat;background-position:center;background-size:cover;background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%2378829D'/%3e%3c/svg%3e\")}.grid-sort-icon:after{display:inline-block;content:\"\";height:.3rem;width:.54rem;background-repeat:no-repeat;background-position:center;background-size:cover;background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%2378829D'/%3e%3c/svg%3e\")}.grid-asc>.grid-sort-icon:before{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%234B5675'/%3e%3c/svg%3e\")}.grid-asc>.grid-sort-icon:after{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%23C4CADA'/%3e%3c/svg%3e\")}.grid-desc>.grid-sort-icon:before{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%23C4CADA'/%3e%3c/svg%3e\")}.grid-desc>.grid-sort-icon:after{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%234B5675'/%3e%3c/svg%3e\")}.cdk-drag-preview{display:table;width:100%;background:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:.4;background-color:#f3f4f6}.cdk-drag-animating,.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2.ɵɵCdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "directive", type: i2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: BkBadge, selector: "bk-badge", inputs: ["label", "variant", "color", "size", "dot", "removable", "customClass"], outputs: ["clicked"] }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition", "bkTooltipScrollable", "bkTooltipMaxHeight", "bkTooltipSize", "bkTooltipAutoHeight"] }, { kind: "component", type: BkCheckbox, selector: "bk-checkbox", inputs: ["checkboxClass", "label", "labelClass", "disabled"], outputs: ["change"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
4822
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkGrid, isStandalone: true, selector: "bk-grid", inputs: { draggable: "draggable", columns: "columns", result: "result", actions: "actions", customClass: "customClass", actionIconClass: "actionIconClass", actionClass: "actionClass", showNoRecords: "showNoRecords", noRecordFoundHeight: "noRecordFoundHeight" }, outputs: { change: "change", actionClick: "actionClick", sortChange: "sortChange", dragDropChange: "dragDropChange" }, viewQueries: [{ propertyName: "tableScrollContainer", first: true, predicate: ["tableScrollContainer"], descendants: true }], ngImport: i0, template: "<div #tableScrollContainer cdkScrollable class=\"overflow-y-auto\" [ngClass]=\"customClass\">\r\n <table class=\"min-w-full text-sm text-left text-gray-800 table-auto border-collapse\">\r\n <!-- ================= HEADER ================= -->\r\n <thead>\r\n <tr>\r\n @for (col of columns; track col.header; let i = $index) {\r\n @if (isColumnVisible(col)) {\r\n <th\r\n class=\"grid-header sticky top-[-1px]\"\r\n [class.cursor-pointer]=\"col.sortable\"\r\n [class.cursor-default]=\"!col.sortable\"\r\n [class.action-sticky]=\"col.sticky\"\r\n [class.z-10]=\"col.sticky\"\r\n class=\"{{ col.headerClass }} {{ col.cellClass }}\"\r\n (click)=\"sort(col, i)\"\r\n >\r\n <!-- [ngClass]=\"col.headerClass\"\r\n [ngClass]=\"col.cellClass\" -->\r\n <span\r\n class=\"flex items-center gap-1\"\r\n [ngClass]=\"\r\n sortColumn === col.field\r\n ? sortDirection === 'asc'\r\n ? 'grid-asc'\r\n : 'grid-desc'\r\n : ''\r\n \"\r\n >\r\n {{ col.header }}\r\n @if (col.sortable) {\r\n <span class=\"grid-sort-icon\"></span>\r\n }\r\n </span>\r\n </th>\r\n }\r\n }\r\n\r\n @if (actions.length) {\r\n <th class=\"grid-header sticky top-0 action-sticky z-10 !bg-[#FBFBFC] w-20 {{actionClass}}\">Action</th>\r\n }\r\n </tr>\r\n </thead>\r\n\r\n <!-- ================= BODY ================= -->\r\n <tbody\r\n cdkDropList\r\n [cdkDropListDisabled]=\"!draggable\"\r\n [cdkDropListData]=\"result || []\"\r\n (cdkDropListDropped)=\"dropList($event)\"\r\n >\r\n @for (row of result; track row; let rowIndex = $index) {\r\n <tr\r\n cdkDrag\r\n cdkDragLockAxis=\"y\"\r\n [cdkDragDisabled]=\"!draggable\"\r\n (cdkDragStarted)=\"onDragStart($event)\"\r\n (cdkDragMoved)=\"onDragMoved($event)\"\r\n class=\"\"\r\n [ngClass]=\"{ 'cursor-move ': draggable }\"\r\n >\r\n @for (col of columns; track col.header; let colIndex = $index) {\r\n @if (isColumnVisible(col)) {\r\n <td class=\"grid-cell text-nowrap\" [ngClass]=\"col.cellClass\">\r\n @if (draggable && colIndex === firstVisibleColumnIndex) {\r\n <span\r\n cdkDragHandle\r\n class=\"mr-2 text-gray-400\"\r\n [ngClass]=\"{ 'cursor-move': draggable }\"\r\n >\u2630</span\r\n >\r\n }\r\n @if (col.checkbox) {\r\n <bk-checkbox\r\n checkboxClass=\"sm\"\r\n [ngModel]=\"getCheckboxValue(row, col)\"\r\n (ngModelChange)=\"setCheckboxValue(row, col, $event)\"\r\n [disabled]=\"typeof col.checkboxDisabled === 'function' ? col.checkboxDisabled(row) : col.checkboxDisabled || false\"\r\n [bkTooltip]=\"typeof col.checkboxTooltip === 'function' ? col.checkboxTooltip(row) : col.checkboxTooltip || ''\"\r\n [bkTooltipPosition]=\"col.checkboxTooltipPosition || 'top'\"\r\n ></bk-checkbox>\r\n } @else if (col.badges) {\r\n @let badge = getBadge(row, col);\r\n @if (badge) {\r\n <bk-badge\r\n [label]=\"badge.label\"\r\n [variant]=\"badge.variant\"\r\n [size]=\"badge.size\"\r\n [color]=\"badge.color\"\r\n [dot]=\"badge.dot\"\r\n [customClass]=\"badge.customClass\"\r\n [bkTooltip]=\"badge.toolTipLabel || ''\"\r\n [bkTooltipPosition]=\"badge.tooltipPosition || 'top'\"\r\n ></bk-badge>\r\n }\r\n } @else if (col.icons) {\r\n @let iconsList = getIcons(row, col);\r\n <div class=\"flex justify-center items-center gap-2\">\r\n @for (icon of iconsList; track $index) {\r\n @if(icon.url){\r\n <img\r\n [src]=\"icon.url\"\r\n class=\"size-4\"\r\n [ngClass]=\"{ 'cursor-pointer': icon.url }\"\r\n [bkTooltip]=\"icon.toolTipLabel || []\"\r\n [bkTooltipPosition]=\"icon.tooltipPosition || 'top'\"\r\n />\r\n }\r\n }\r\n </div>\r\n } @else if (col.toolTipField) {\r\n <span\r\n [bkTooltip]=\"getTooltipValue(row, col)\"\r\n [bkTooltipPosition]=\"col.toolTipPosition || 'top'\"\r\n >\r\n {{ getCellValue(row, col) }}\r\n </span>\r\n } @else {\r\n {{ getCellValue(row, col) }}\r\n }\r\n </td>\r\n }\r\n }\r\n\r\n @if (getRowActions(row).length) {\r\n <td class=\"grid-cell action-sticky text-center\">\r\n <div class=\"flex items-center justify-center gap-1.5\">\r\n @for (action of getRowActions(row); track action.name) {\r\n @if (isActionVisible(action, row)) {\r\n <button\r\n [bkTooltip]=\"action.tooltip\"\r\n [bkTooltipPosition]=\"action?.tooltipPosition || 'top'\"\r\n class=\"size-6 flex items-center justify-center rounded hover:bg-[#F8F8FA] {{actionIconClass}}\"\r\n (click)=\"emitAction(action, row)\"\r\n [disabled]=\"isActionDisabled(action, row)\"\r\n >\r\n <img [src]=\"action.icon\" width=\"14\" height=\"14\" alt=\"action-icon\" />\r\n </button>\r\n }\r\n }\r\n </div>\r\n </td>\r\n }\r\n </tr>\r\n }\r\n @if (showNoRecords) {\r\n <tr>\r\n <td\r\n [attr.colspan]=\"columns.length + (actions.length ? 1 : 0)\"\r\n class=\"text-center py-10 {{ noRecordFoundHeight }}\"\r\n >\r\n <div class=\"flex flex-col justify-center items-center w-full h-auto\">\r\n <img\r\n src=\"./assets/media/logos/no-data-found.jpg\"\r\n class=\"mb-3 w-96\"\r\n alt=\"No data found\"\r\n />\r\n\r\n <span class=\"block text-sm leading-3 text-center font-semibold text-[#60646C] mt-2\"\r\n >Data may be empty, or try adjusting your filter.</span\r\n >\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>\r\n", styles: [".grid-header{@apply bg-[#F9FAFA] text-xs text-[#60646C] font-semibold capitalize px-[17px] py-2.5 whitespace-nowrap;box-shadow:0 1px #ebedf3;-webkit-transform:translateZ(0);transform:translateZ(0);backface-visibility:hidden;-webkit-backface-visibility:hidden}thead tr th:first-child{border-top-left-radius:.75rem}thead tr th:last-child{border-top-right-radius:.75rem}.grid-cell{@apply text-[#15191E] text-[13px] font-medium leading-4 px-4 py-2 border-x border-b border-[#EBEDF3];}.grid-cell:last-child{@apply border-e-0;}.grid-cell:first-child,.grid-first-cell{@apply border-s-0;}.grid-last-cell{@apply border-e-0;}.grid-action-sticky{@apply sticky bg-white right-[.1px] z-[1px];}.grid-action-sticky:before{@apply absolute top-0 bottom-0 left-[-8px] w-2;content:\"\";background-image:linear-gradient(to left,rgba(0,0,0,.05),transparent)}.grid-required{@apply font-medium text-sm leading-normal after:content-[\"*\"] after:text-[#C10007] after:ms-0.5;}.grid-sort{display:inline-flex;align-items:center;gap:.35rem;cursor:pointer;line-height:1}.grid-sort-icon{display:inline-flex;flex-direction:column;justify-content:center;align-items:center;height:.875rem;width:.875rem;gap:.125rem;line-height:1}.grid-sort-icon:before{display:inline-block;content:\"\";height:.3rem;width:.54rem;background-repeat:no-repeat;background-position:center;background-size:cover;background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%2378829D'/%3e%3c/svg%3e\")}.grid-sort-icon:after{display:inline-block;content:\"\";height:.3rem;width:.54rem;background-repeat:no-repeat;background-position:center;background-size:cover;background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%2378829D'/%3e%3c/svg%3e\")}.grid-asc>.grid-sort-icon:before{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%234B5675'/%3e%3c/svg%3e\")}.grid-asc>.grid-sort-icon:after{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%23C4CADA'/%3e%3c/svg%3e\")}.grid-desc>.grid-sort-icon:before{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M1.08333 4.83333C0.908333 4.83333 0.791667 4.775 0.675 4.65833C0.441667 4.425 0.441667 4.075 0.675 3.84167L3.59167 0.925C3.825 0.691667 4.175 0.691667 4.40833 0.925L7.325 3.84167C7.55833 4.075 7.55833 4.425 7.325 4.65833C7.09167 4.89167 6.74167 4.89167 6.50833 4.65833L4 2.15L1.49167 4.65833C1.375 4.775 1.25833 4.83333 1.08333 4.83333Z' fill='%23C4CADA'/%3e%3c/svg%3e\")}.grid-desc>.grid-sort-icon:after{background-image:url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5' fill='none'%3e%3cpath d='M4 4.24984C3.825 4.24984 3.70833 4.1915 3.59167 4.07484L0.675 1.15817C0.441667 0.924838 0.441667 0.574837 0.675 0.341504C0.908333 0.108171 1.25833 0.108171 1.49167 0.341504L4 2.84984L6.50833 0.341504C6.74167 0.108171 7.09167 0.108171 7.325 0.341504C7.55833 0.574837 7.55833 0.924838 7.325 1.15817L4.40833 4.07484C4.29167 4.1915 4.175 4.24984 4 4.24984Z' fill='%234B5675'/%3e%3c/svg%3e\")}.cdk-drag-preview{display:table;width:100%;background:#fff;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}.cdk-drag-placeholder{opacity:.4;background-color:#f3f4f6}.cdk-drag-animating,.cdk-drop-list-dragging .cdk-drag{transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2$1.ɵɵCdkScrollable, selector: "[cdk-scrollable], [cdkScrollable]" }, { kind: "directive", type: i2$1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2$1.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "component", type: BkBadge, selector: "bk-badge", inputs: ["label", "variant", "color", "size", "dot", "removable", "customClass"], outputs: ["clicked"] }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition", "bkTooltipScrollable", "bkTooltipMaxHeight", "bkTooltipSize", "bkTooltipAutoHeight"] }, { kind: "component", type: BkCheckbox, selector: "bk-checkbox", inputs: ["checkboxClass", "label", "labelClass", "disabled"], outputs: ["change"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
4823
4823
|
}
|
|
4824
4824
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkGrid, decorators: [{
|
|
4825
4825
|
type: Component,
|
|
@@ -4855,6 +4855,305 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
4855
4855
|
args: ['tableScrollContainer', { static: false }]
|
|
4856
4856
|
}] } });
|
|
4857
4857
|
|
|
4858
|
+
class BkAvatar {
|
|
4859
|
+
cdr;
|
|
4860
|
+
constructor(cdr) {
|
|
4861
|
+
this.cdr = cdr;
|
|
4862
|
+
}
|
|
4863
|
+
// ---------- Display Inputs ----------
|
|
4864
|
+
src = null;
|
|
4865
|
+
alt = 'Avatar';
|
|
4866
|
+
name = '';
|
|
4867
|
+
initialsOverride = '';
|
|
4868
|
+
tooltipContent = null;
|
|
4869
|
+
bgColor = null;
|
|
4870
|
+
textColor = null;
|
|
4871
|
+
size = 'md';
|
|
4872
|
+
variant = 'gray';
|
|
4873
|
+
fallback = 'auto';
|
|
4874
|
+
dot = 'none';
|
|
4875
|
+
dotPosition = 'bottom-right';
|
|
4876
|
+
// ---------- Outputs ----------
|
|
4877
|
+
/** Emits when the provided image URL fails to load */
|
|
4878
|
+
imageLoadError = new EventEmitter();
|
|
4879
|
+
// ---------- Internal State ----------
|
|
4880
|
+
initials = '';
|
|
4881
|
+
imageLoadFailed = false;
|
|
4882
|
+
// ---------- CVA Callbacks ----------
|
|
4883
|
+
onChange = (_value) => { };
|
|
4884
|
+
onTouched = () => { };
|
|
4885
|
+
/**
|
|
4886
|
+
* Called by the forms system when the model value changes (ngModel / formControl).
|
|
4887
|
+
* Sets the src directly and tells OnPush to re-check the template.
|
|
4888
|
+
*/
|
|
4889
|
+
writeValue(value) {
|
|
4890
|
+
this.src = value || null;
|
|
4891
|
+
this.imageLoadFailed = false;
|
|
4892
|
+
// OnPush won't detect this change on its own because writeValue
|
|
4893
|
+
// is called programmatically by the forms system — not through an
|
|
4894
|
+
// @Input binding. markForCheck tells Angular: "this component's
|
|
4895
|
+
// template might have changed, check it on the next CD cycle."
|
|
4896
|
+
this.cdr.markForCheck();
|
|
4897
|
+
}
|
|
4898
|
+
registerOnChange(fn) {
|
|
4899
|
+
this.onChange = fn;
|
|
4900
|
+
}
|
|
4901
|
+
registerOnTouched(fn) {
|
|
4902
|
+
this.onTouched = fn;
|
|
4903
|
+
}
|
|
4904
|
+
setDisabledState(_isDisabled) {
|
|
4905
|
+
// Display-only component — disabled doesn't change visual behaviour,
|
|
4906
|
+
// but we still honour the CVA contract.
|
|
4907
|
+
this.cdr.markForCheck();
|
|
4908
|
+
}
|
|
4909
|
+
// ---------- Lifecycle ----------
|
|
4910
|
+
ngOnChanges(changes) {
|
|
4911
|
+
if (changes['name'] || changes['initialsOverride']) {
|
|
4912
|
+
this.initials = this.initialsOverride || this.getInitials(this.name);
|
|
4913
|
+
}
|
|
4914
|
+
// Reset error state whenever a new src arrives via @Input
|
|
4915
|
+
if (changes['src']) {
|
|
4916
|
+
this.imageLoadFailed = false;
|
|
4917
|
+
}
|
|
4918
|
+
}
|
|
4919
|
+
onImageError() {
|
|
4920
|
+
this.imageLoadFailed = true;
|
|
4921
|
+
this.imageLoadError.emit();
|
|
4922
|
+
}
|
|
4923
|
+
// ---------- Derived UI ----------
|
|
4924
|
+
get showImage() {
|
|
4925
|
+
return !!(this.src) && !this.imageLoadFailed;
|
|
4926
|
+
}
|
|
4927
|
+
get showInitials() {
|
|
4928
|
+
if (this.showImage)
|
|
4929
|
+
return false;
|
|
4930
|
+
if (!this.name)
|
|
4931
|
+
return false;
|
|
4932
|
+
if (this.fallback === 'icon')
|
|
4933
|
+
return false;
|
|
4934
|
+
return true; // 'auto' and 'initials' both show initials when name is present
|
|
4935
|
+
}
|
|
4936
|
+
get showIcon() {
|
|
4937
|
+
return !this.showImage && !this.showInitials;
|
|
4938
|
+
}
|
|
4939
|
+
get containerClasses() {
|
|
4940
|
+
return [
|
|
4941
|
+
'avatar',
|
|
4942
|
+
this.size,
|
|
4943
|
+
VARIANT_MAP[this.variant]
|
|
4944
|
+
].join(' ');
|
|
4945
|
+
}
|
|
4946
|
+
get containerStyles() {
|
|
4947
|
+
const styles = {};
|
|
4948
|
+
if (this.bgColor) {
|
|
4949
|
+
styles['background'] = this.bgColor;
|
|
4950
|
+
}
|
|
4951
|
+
if (this.textColor) {
|
|
4952
|
+
styles['color'] = this.textColor;
|
|
4953
|
+
}
|
|
4954
|
+
return Object.keys(styles).length ? styles : null;
|
|
4955
|
+
}
|
|
4956
|
+
get resolvedTooltip() {
|
|
4957
|
+
return this.tooltipContent ?? this.name;
|
|
4958
|
+
}
|
|
4959
|
+
get dotClasses() {
|
|
4960
|
+
return [
|
|
4961
|
+
'avatar-dot',
|
|
4962
|
+
this.size,
|
|
4963
|
+
DOT_COLOR_MAP[this.dot],
|
|
4964
|
+
DOT_POSITION_MAP[this.dotPosition]
|
|
4965
|
+
].join(' ');
|
|
4966
|
+
}
|
|
4967
|
+
// ---------- Utils ----------
|
|
4968
|
+
getInitials(name) {
|
|
4969
|
+
if (!name?.trim())
|
|
4970
|
+
return '';
|
|
4971
|
+
const normalized = name.includes(',')
|
|
4972
|
+
? name.split(',').map(part => part.trim()).filter(Boolean).reverse().join(' ')
|
|
4973
|
+
: name.trim();
|
|
4974
|
+
const parts = normalized.split(/\s+/);
|
|
4975
|
+
if (parts.length === 1) {
|
|
4976
|
+
return parts[0].slice(0, 2).toUpperCase();
|
|
4977
|
+
}
|
|
4978
|
+
return (parts[0][0] + parts.at(-1)[0]).toUpperCase();
|
|
4979
|
+
}
|
|
4980
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkAvatar, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4981
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkAvatar, isStandalone: true, selector: "bk-avatar", inputs: { src: "src", alt: "alt", name: "name", initialsOverride: "initialsOverride", tooltipContent: "tooltipContent", bgColor: "bgColor", textColor: "textColor", size: "size", variant: "variant", fallback: "fallback", dot: "dot", dotPosition: "dotPosition" }, outputs: { imageLoadError: "imageLoadError" }, providers: [
|
|
4982
|
+
{
|
|
4983
|
+
provide: NG_VALUE_ACCESSOR,
|
|
4984
|
+
useExisting: forwardRef(() => BkAvatar),
|
|
4985
|
+
multi: true
|
|
4986
|
+
}
|
|
4987
|
+
], usesOnChanges: true, ngImport: i0, template: "<div\r\n [ngClass]=\"containerClasses\"\r\n [ngStyle]=\"containerStyles\"\r\n [bkTooltip]=\"resolvedTooltip\"\r\n [bkTooltipPosition]=\"'top'\"\r\n>\r\n\r\n @if (showImage) {\r\n <img\r\n [src]=\"src\"\r\n [alt]=\"alt\"\r\n class=\"avatar-img\"\r\n (error)=\"onImageError()\"\r\n />\r\n }\r\n\r\n @else if (showInitials) {\r\n <span class=\"avatar-text\">\r\n {{ initials }}\r\n </span>\r\n }\r\n\r\n @else {\r\n <svg\r\n class=\"placeholder-icon\"\r\n viewBox=\"0 0 32 32\"\r\n fill=\"none\"\r\n aria-hidden=\"true\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M16 16c3.682 0 6.667-2.985 6.667-6.667S19.682 2.667 16 2.667 9.333 5.651 9.333 9.333 12.318 16 16 16Z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M27.453 29.333C27.453 24.173 22.32 20 16 20S4.547 24.173 4.547 29.333\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (dot !== 'none') {\r\n <span [ngClass]=\"dotClasses\"></span>\r\n }\r\n\r\n</div>\r\n", styles: [".avatar{@apply relative inline-flex items-center justify-center rounded-full flex-shrink-0 select-none;}.avatar-img{@apply w-full h-full object-cover rounded-full;}.avatar-text{@apply font-medium;}.avatar.xxsm{@apply size-4 text-[8px] leading-[10px];}.avatar.xsm{@apply size-6 text-[10px] leading-[14px];}.avatar.sm{@apply size-8 text-sm;}.avatar.md{@apply size-10 text-base;}.avatar.lg{@apply size-12 text-[18px] leading-[26px];}.avatar.xl{@apply size-14 text-xl;}.avatar.xxl{@apply size-16 text-xl;}.avatar.xxsm .placeholder-icon{@apply size-3;}.avatar.xsm .placeholder-icon{@apply size-4;}.avatar.sm .placeholder-icon{@apply size-5;}.avatar.md .placeholder-icon{@apply size-6;}.avatar.lg .placeholder-icon{@apply size-7;}.avatar.xl .placeholder-icon,.avatar.xxl .placeholder-icon{@apply size-8;}.avatar-dot{@apply absolute rounded-full block box-content border-[1.5px] border-white;}.avatar.xxsm .avatar-dot,.avatar.xsm .avatar-dot{@apply size-1;}.avatar.sm .avatar-dot{@apply size-1.5;}.avatar.md .avatar-dot{@apply size-2.5;}.avatar.lg .avatar-dot{@apply size-3;}.avatar.xl .avatar-dot{@apply size-[14px];}.avatar.xxl .avatar-dot{@apply size-4;}.avatar .active{@apply bg-[#22973F];}.avatar .inactive{@apply bg-gray-300;}.avatar .notification{@apply bg-[#2E90FA];}.avatar .none{@apply hidden;}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition", "bkTooltipScrollable", "bkTooltipMaxHeight", "bkTooltipSize", "bkTooltipAutoHeight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4988
|
+
}
|
|
4989
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkAvatar, decorators: [{
|
|
4990
|
+
type: Component,
|
|
4991
|
+
args: [{ selector: 'bk-avatar', standalone: true, imports: [CommonModule, BKTooltipDirective], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
4992
|
+
{
|
|
4993
|
+
provide: NG_VALUE_ACCESSOR,
|
|
4994
|
+
useExisting: forwardRef(() => BkAvatar),
|
|
4995
|
+
multi: true
|
|
4996
|
+
}
|
|
4997
|
+
], template: "<div\r\n [ngClass]=\"containerClasses\"\r\n [ngStyle]=\"containerStyles\"\r\n [bkTooltip]=\"resolvedTooltip\"\r\n [bkTooltipPosition]=\"'top'\"\r\n>\r\n\r\n @if (showImage) {\r\n <img\r\n [src]=\"src\"\r\n [alt]=\"alt\"\r\n class=\"avatar-img\"\r\n (error)=\"onImageError()\"\r\n />\r\n }\r\n\r\n @else if (showInitials) {\r\n <span class=\"avatar-text\">\r\n {{ initials }}\r\n </span>\r\n }\r\n\r\n @else {\r\n <svg\r\n class=\"placeholder-icon\"\r\n viewBox=\"0 0 32 32\"\r\n fill=\"none\"\r\n aria-hidden=\"true\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M16 16c3.682 0 6.667-2.985 6.667-6.667S19.682 2.667 16 2.667 9.333 5.651 9.333 9.333 12.318 16 16 16Z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M27.453 29.333C27.453 24.173 22.32 20 16 20S4.547 24.173 4.547 29.333\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (dot !== 'none') {\r\n <span [ngClass]=\"dotClasses\"></span>\r\n }\r\n\r\n</div>\r\n", styles: [".avatar{@apply relative inline-flex items-center justify-center rounded-full flex-shrink-0 select-none;}.avatar-img{@apply w-full h-full object-cover rounded-full;}.avatar-text{@apply font-medium;}.avatar.xxsm{@apply size-4 text-[8px] leading-[10px];}.avatar.xsm{@apply size-6 text-[10px] leading-[14px];}.avatar.sm{@apply size-8 text-sm;}.avatar.md{@apply size-10 text-base;}.avatar.lg{@apply size-12 text-[18px] leading-[26px];}.avatar.xl{@apply size-14 text-xl;}.avatar.xxl{@apply size-16 text-xl;}.avatar.xxsm .placeholder-icon{@apply size-3;}.avatar.xsm .placeholder-icon{@apply size-4;}.avatar.sm .placeholder-icon{@apply size-5;}.avatar.md .placeholder-icon{@apply size-6;}.avatar.lg .placeholder-icon{@apply size-7;}.avatar.xl .placeholder-icon,.avatar.xxl .placeholder-icon{@apply size-8;}.avatar-dot{@apply absolute rounded-full block box-content border-[1.5px] border-white;}.avatar.xxsm .avatar-dot,.avatar.xsm .avatar-dot{@apply size-1;}.avatar.sm .avatar-dot{@apply size-1.5;}.avatar.md .avatar-dot{@apply size-2.5;}.avatar.lg .avatar-dot{@apply size-3;}.avatar.xl .avatar-dot{@apply size-[14px];}.avatar.xxl .avatar-dot{@apply size-4;}.avatar .active{@apply bg-[#22973F];}.avatar .inactive{@apply bg-gray-300;}.avatar .notification{@apply bg-[#2E90FA];}.avatar .none{@apply hidden;}\n"] }]
|
|
4998
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { src: [{
|
|
4999
|
+
type: Input
|
|
5000
|
+
}], alt: [{
|
|
5001
|
+
type: Input
|
|
5002
|
+
}], name: [{
|
|
5003
|
+
type: Input
|
|
5004
|
+
}], initialsOverride: [{
|
|
5005
|
+
type: Input
|
|
5006
|
+
}], tooltipContent: [{
|
|
5007
|
+
type: Input
|
|
5008
|
+
}], bgColor: [{
|
|
5009
|
+
type: Input
|
|
5010
|
+
}], textColor: [{
|
|
5011
|
+
type: Input
|
|
5012
|
+
}], size: [{
|
|
5013
|
+
type: Input
|
|
5014
|
+
}], variant: [{
|
|
5015
|
+
type: Input
|
|
5016
|
+
}], fallback: [{
|
|
5017
|
+
type: Input
|
|
5018
|
+
}], dot: [{
|
|
5019
|
+
type: Input
|
|
5020
|
+
}], dotPosition: [{
|
|
5021
|
+
type: Input
|
|
5022
|
+
}], imageLoadError: [{
|
|
5023
|
+
type: Output
|
|
5024
|
+
}] } });
|
|
5025
|
+
// ---------- Constants ----------
|
|
5026
|
+
const VARIANT_MAP = {
|
|
5027
|
+
gray: 'bg-white border border-[#EFEFF1] text-[#363C51]',
|
|
5028
|
+
colored: 'bg-[#F63D68] border border-white text-white'
|
|
5029
|
+
};
|
|
5030
|
+
const DOT_COLOR_MAP = {
|
|
5031
|
+
active: 'active',
|
|
5032
|
+
inactive: 'inactive',
|
|
5033
|
+
notification: 'notification',
|
|
5034
|
+
none: 'hidden'
|
|
5035
|
+
};
|
|
5036
|
+
const DOT_POSITION_MAP = {
|
|
5037
|
+
'bottom-right': 'bottom-0 right-0',
|
|
5038
|
+
'top-left': 'top-0.5 -left-0.5'
|
|
5039
|
+
};
|
|
5040
|
+
|
|
5041
|
+
/* =========================================================================
|
|
5042
|
+
Derives a full UI appearance (background / text / border / dot) from a
|
|
5043
|
+
single accent colour. Shared by bk-status-select, bk-select and
|
|
5044
|
+
bk-hierarchical-select so colour handling stays identical across all three.
|
|
5045
|
+
========================================================================= */
|
|
5046
|
+
const BLACK = { r: 0, g: 0, b: 0 };
|
|
5047
|
+
const WHITE = { r: 255, g: 255, b: 255 };
|
|
5048
|
+
const HEX3 = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i;
|
|
5049
|
+
const HEX6 = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i;
|
|
5050
|
+
const RGB_FN = /^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i;
|
|
5051
|
+
/** The neutral look used when there is no colour (or an unparseable one). */
|
|
5052
|
+
const NEUTRAL_APPEARANCE = {
|
|
5053
|
+
backgroundColor: null,
|
|
5054
|
+
color: null,
|
|
5055
|
+
borderColor: null,
|
|
5056
|
+
dotColor: null
|
|
5057
|
+
};
|
|
5058
|
+
/**
|
|
5059
|
+
* Parses hex and rgb()/rgba() colours. Named CSS colours ("red") are not
|
|
5060
|
+
* supported — they'd need a live DOM to resolve — and return null, which makes
|
|
5061
|
+
* the caller fall back to the neutral (uncoloured) appearance.
|
|
5062
|
+
*/
|
|
5063
|
+
function parseColor(input) {
|
|
5064
|
+
if (!input)
|
|
5065
|
+
return null;
|
|
5066
|
+
const s = String(input).trim();
|
|
5067
|
+
let m = HEX3.exec(s);
|
|
5068
|
+
if (m) {
|
|
5069
|
+
return {
|
|
5070
|
+
r: parseInt(m[1] + m[1], 16),
|
|
5071
|
+
g: parseInt(m[2] + m[2], 16),
|
|
5072
|
+
b: parseInt(m[3] + m[3], 16)
|
|
5073
|
+
};
|
|
5074
|
+
}
|
|
5075
|
+
m = HEX6.exec(s);
|
|
5076
|
+
if (m) {
|
|
5077
|
+
return { r: parseInt(m[1], 16), g: parseInt(m[2], 16), b: parseInt(m[3], 16) };
|
|
5078
|
+
}
|
|
5079
|
+
m = RGB_FN.exec(s);
|
|
5080
|
+
if (m) {
|
|
5081
|
+
return { r: clampChannel(+m[1]), g: clampChannel(+m[2]), b: clampChannel(+m[3]) };
|
|
5082
|
+
}
|
|
5083
|
+
return null;
|
|
5084
|
+
}
|
|
5085
|
+
function clampChannel(v) {
|
|
5086
|
+
return Math.max(0, Math.min(255, Math.round(v)));
|
|
5087
|
+
}
|
|
5088
|
+
/** WCAG relative luminance — used to decide whether text needs to be light or dark. */
|
|
5089
|
+
function luminance({ r, g, b }) {
|
|
5090
|
+
const [lr, lg, lb] = [r, g, b].map(v => {
|
|
5091
|
+
const c = v / 255;
|
|
5092
|
+
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
5093
|
+
});
|
|
5094
|
+
return 0.2126 * lr + 0.7152 * lg + 0.0722 * lb;
|
|
5095
|
+
}
|
|
5096
|
+
/** Linear blend of `c` toward `target`. amount 0 = c, 1 = target. */
|
|
5097
|
+
function mix(c, target, amount) {
|
|
5098
|
+
return {
|
|
5099
|
+
r: Math.round(c.r + (target.r - c.r) * amount),
|
|
5100
|
+
g: Math.round(c.g + (target.g - c.g) * amount),
|
|
5101
|
+
b: Math.round(c.b + (target.b - c.b) * amount)
|
|
5102
|
+
};
|
|
5103
|
+
}
|
|
5104
|
+
/**
|
|
5105
|
+
* Darkens a colour until it reads acceptably as text on a light tint. Pastel
|
|
5106
|
+
* accents (light yellows, mints) are unreadable at full strength, so they get
|
|
5107
|
+
* stepped toward black; already-dark accents pass through untouched.
|
|
5108
|
+
*/
|
|
5109
|
+
function readableOnLight(c) {
|
|
5110
|
+
let out = c;
|
|
5111
|
+
let guard = 0;
|
|
5112
|
+
while (luminance(out) > 0.4 && guard < 12) {
|
|
5113
|
+
out = mix(out, BLACK, 0.2);
|
|
5114
|
+
guard++;
|
|
5115
|
+
}
|
|
5116
|
+
return out;
|
|
5117
|
+
}
|
|
5118
|
+
function rgbString({ r, g, b }) {
|
|
5119
|
+
return `rgb(${r}, ${g}, ${b})`;
|
|
5120
|
+
}
|
|
5121
|
+
function rgbaString({ r, g, b }, alpha) {
|
|
5122
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
5123
|
+
}
|
|
5124
|
+
/**
|
|
5125
|
+
* Derives every colour the UI needs from a single accent colour.
|
|
5126
|
+
*
|
|
5127
|
+
* subtle → soft tint of the accent, accent-coloured (darkened if needed) text.
|
|
5128
|
+
* solid → accent as the background, white or near-black text by contrast.
|
|
5129
|
+
* none → no background; only the dot and text carry the accent.
|
|
5130
|
+
*/
|
|
5131
|
+
function deriveAppearance(color, fill = 'subtle') {
|
|
5132
|
+
const rgb = parseColor(color);
|
|
5133
|
+
if (!rgb)
|
|
5134
|
+
return NEUTRAL_APPEARANCE;
|
|
5135
|
+
const dotColor = rgbString(rgb);
|
|
5136
|
+
if (fill === 'solid') {
|
|
5137
|
+
return {
|
|
5138
|
+
backgroundColor: dotColor,
|
|
5139
|
+
color: luminance(rgb) > 0.5 ? '#141414' : '#FFFFFF',
|
|
5140
|
+
borderColor: rgbString(mix(rgb, BLACK, 0.08)),
|
|
5141
|
+
// On a solid accent background the dot must contrast with the accent itself.
|
|
5142
|
+
dotColor: luminance(rgb) > 0.5 ? rgbaString(BLACK, 0.55) : rgbaString(WHITE, 0.85)
|
|
5143
|
+
};
|
|
5144
|
+
}
|
|
5145
|
+
const text = rgbString(readableOnLight(rgb));
|
|
5146
|
+
if (fill === 'none') {
|
|
5147
|
+
return { backgroundColor: null, color: text, borderColor: null, dotColor };
|
|
5148
|
+
}
|
|
5149
|
+
return {
|
|
5150
|
+
backgroundColor: rgbaString(rgb, 0.12),
|
|
5151
|
+
color: text,
|
|
5152
|
+
borderColor: rgbaString(rgb, 0.28),
|
|
5153
|
+
dotColor
|
|
5154
|
+
};
|
|
5155
|
+
}
|
|
5156
|
+
|
|
4858
5157
|
class BkSelect {
|
|
4859
5158
|
// --- Inputs ---
|
|
4860
5159
|
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
@@ -4868,6 +5167,32 @@ class BkSelect {
|
|
|
4868
5167
|
clearAllText = input('Clear all', ...(ngDevMode ? [{ debugName: "clearAllText" }] : []));
|
|
4869
5168
|
groupBy = input('', ...(ngDevMode ? [{ debugName: "groupBy" }] : [])); // NEW
|
|
4870
5169
|
colorKey = input('', ...(ngDevMode ? [{ debugName: "colorKey" }] : [])); // e.g. "color"
|
|
5170
|
+
/**
|
|
5171
|
+
* Show an accent dot beside each option, driven by `colorKey`.
|
|
5172
|
+
*
|
|
5173
|
+
* In single-select mode the control is also tinted with the selected option's
|
|
5174
|
+
* colour (same treatment as bk-status-select), unless `hasError` is set — an
|
|
5175
|
+
* errored control drops the accent for a soft red tint instead. Multi-select
|
|
5176
|
+
* never tints the control: one background can't represent several colours, so
|
|
5177
|
+
* the accents are carried on the chips instead.
|
|
5178
|
+
*
|
|
5179
|
+
* Only one leading visual renders per row — precedence is avatar > icon > dot
|
|
5180
|
+
* — so the dot appears only when `showAvatar` is off and the item has no icon.
|
|
5181
|
+
*/
|
|
5182
|
+
showDots = input(false, ...(ngDevMode ? [{ debugName: "showDots" }] : []));
|
|
5183
|
+
/**
|
|
5184
|
+
* Render an avatar before each option label: the `avatarKey` image when the
|
|
5185
|
+
* item has one, otherwise initials derived from the label ("mtayyab" → "MT").
|
|
5186
|
+
* Replaces the plain icon <img> in options and the single-select value.
|
|
5187
|
+
*/
|
|
5188
|
+
showAvatar = input(false, ...(ngDevMode ? [{ debugName: "showAvatar" }] : []));
|
|
5189
|
+
/**
|
|
5190
|
+
* Key holding the avatar image URL, used only when `showAvatar` is on.
|
|
5191
|
+
* Falls back to `bindIcon` when unset. Kept separate from `bindIcon` so the
|
|
5192
|
+
* plain icon feature stays independent — an item's icon should not appear
|
|
5193
|
+
* as a bare <img> just because it also has an avatar.
|
|
5194
|
+
*/
|
|
5195
|
+
avatarKey = input('', ...(ngDevMode ? [{ debugName: "avatarKey" }] : []));
|
|
4871
5196
|
// iconSrc = input<string>('Clear all');
|
|
4872
5197
|
iconAlt = 'icon';
|
|
4873
5198
|
label = '';
|
|
@@ -4944,6 +5269,11 @@ class BkSelect {
|
|
|
4944
5269
|
return label.includes(term);
|
|
4945
5270
|
});
|
|
4946
5271
|
}, ...(ngDevMode ? [{ debugName: "filteredItems" }] : []));
|
|
5272
|
+
/**
|
|
5273
|
+
* True when the user is allowed to change the selection. Both disabled and
|
|
5274
|
+
* readonly lock the control, so neither may offer a remove/clear affordance.
|
|
5275
|
+
*/
|
|
5276
|
+
isEditable = computed(() => !this.disabled() && !this.readonly(), ...(ngDevMode ? [{ debugName: "isEditable" }] : []));
|
|
4947
5277
|
isAllSelected = computed(() => {
|
|
4948
5278
|
const filtered = this.filteredItems();
|
|
4949
5279
|
const current = this.selectedOptions();
|
|
@@ -5323,11 +5653,15 @@ class BkSelect {
|
|
|
5323
5653
|
}
|
|
5324
5654
|
removeOption(item, event) {
|
|
5325
5655
|
event.stopPropagation();
|
|
5656
|
+
if (!this.isEditable())
|
|
5657
|
+
return;
|
|
5326
5658
|
const newSelection = this.selectedOptions().filter(i => i !== item);
|
|
5327
5659
|
this.updateModel(newSelection);
|
|
5328
5660
|
}
|
|
5329
5661
|
handleClear(event) {
|
|
5330
5662
|
event.stopPropagation();
|
|
5663
|
+
if (!this.isEditable())
|
|
5664
|
+
return;
|
|
5331
5665
|
this.updateModel([]);
|
|
5332
5666
|
this.clear.emit(null);
|
|
5333
5667
|
}
|
|
@@ -5486,12 +5820,73 @@ class BkSelect {
|
|
|
5486
5820
|
const key = this.colorKey();
|
|
5487
5821
|
return key && typeof item === 'object' ? item[key] : null;
|
|
5488
5822
|
}
|
|
5823
|
+
/**
|
|
5824
|
+
* Colours for the control itself. Single-select only: with several chips
|
|
5825
|
+
* selected there is no single accent that could represent them, so multi
|
|
5826
|
+
* mode stays neutral and relies on per-chip dots.
|
|
5827
|
+
*/
|
|
5828
|
+
controlAppearance = computed(() => {
|
|
5829
|
+
if (!this.showDots() || this.multiple())
|
|
5830
|
+
return NEUTRAL_APPEARANCE;
|
|
5831
|
+
const selected = this.selectedOptions()[0];
|
|
5832
|
+
if (!selected)
|
|
5833
|
+
return NEUTRAL_APPEARANCE;
|
|
5834
|
+
return deriveAppearance(this.resolveColor(selected), 'subtle');
|
|
5835
|
+
}, ...(ngDevMode ? [{ debugName: "controlAppearance" }] : []));
|
|
5836
|
+
/**
|
|
5837
|
+
* Tint for an errored control, derived from the same red as the error border
|
|
5838
|
+
* so the control reads as one state rather than a red outline over a colour.
|
|
5839
|
+
*/
|
|
5840
|
+
static ERROR_APPEARANCE = deriveAppearance('#D11E14', 'subtle');
|
|
5841
|
+
/**
|
|
5842
|
+
* Colours actually applied to the control. An option's accent never survives
|
|
5843
|
+
* an error: the tint is swapped for a soft red one so the error can't be
|
|
5844
|
+
* mistaken for a status colour. Only tintable controls have anything to swap
|
|
5845
|
+
* — a multi-select is neutral either way, since one background can't stand in
|
|
5846
|
+
* for several chips.
|
|
5847
|
+
*/
|
|
5848
|
+
controlStyle() {
|
|
5849
|
+
if (!this.hasError)
|
|
5850
|
+
return this.controlAppearance();
|
|
5851
|
+
return this.showDots() && !this.multiple()
|
|
5852
|
+
? BkSelect.ERROR_APPEARANCE
|
|
5853
|
+
: NEUTRAL_APPEARANCE;
|
|
5854
|
+
}
|
|
5855
|
+
/** Raw accent for an option's dot. Null when the item has no usable colour. */
|
|
5856
|
+
accentFor(item) {
|
|
5857
|
+
return deriveAppearance(this.resolveColor(item), 'subtle').dotColor;
|
|
5858
|
+
}
|
|
5859
|
+
/**
|
|
5860
|
+
* Label colour for an option/chip. With showDots on, the accent is darkened
|
|
5861
|
+
* until it stays legible (a pale accent as raw text is unreadable); otherwise
|
|
5862
|
+
* the raw colorKey value is used, preserving the previous behaviour.
|
|
5863
|
+
*/
|
|
5864
|
+
optionTextColor(item) {
|
|
5865
|
+
if (!this.showDots())
|
|
5866
|
+
return this.resolveColor(item);
|
|
5867
|
+
return deriveAppearance(this.resolveColor(item), 'none').color;
|
|
5868
|
+
}
|
|
5869
|
+
/** Soft tint for an option's avatar, so it matches the option's accent. */
|
|
5870
|
+
avatarBgFor(item) {
|
|
5871
|
+
return deriveAppearance(this.resolveColor(item), 'subtle').backgroundColor;
|
|
5872
|
+
}
|
|
5873
|
+
/** Readable text colour paired with avatarBgFor. */
|
|
5874
|
+
avatarTextFor(item) {
|
|
5875
|
+
return deriveAppearance(this.resolveColor(item), 'subtle').color;
|
|
5876
|
+
}
|
|
5489
5877
|
resolveIcon(item) {
|
|
5490
5878
|
if (!item)
|
|
5491
5879
|
return null;
|
|
5492
5880
|
const key = this.bindIcon();
|
|
5493
5881
|
return key && typeof item === 'object' ? item[key] ?? null : null;
|
|
5494
5882
|
}
|
|
5883
|
+
/** Image for the avatar. Prefers `avatarKey`, falling back to `bindIcon`. */
|
|
5884
|
+
resolveAvatarSrc(item) {
|
|
5885
|
+
if (!item || typeof item !== 'object')
|
|
5886
|
+
return null;
|
|
5887
|
+
const key = this.avatarKey() || this.bindIcon();
|
|
5888
|
+
return key ? item[key] ?? null : null;
|
|
5889
|
+
}
|
|
5495
5890
|
getRemainingItems() {
|
|
5496
5891
|
return this.selectedOptions()
|
|
5497
5892
|
.slice(this.visibleCount())
|
|
@@ -5506,24 +5901,24 @@ class BkSelect {
|
|
|
5506
5901
|
this.markedIndex.set(index);
|
|
5507
5902
|
}
|
|
5508
5903
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5509
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkSelect, isStandalone: true, selector: "bk-select", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, bindLabel: { classPropertyName: "bindLabel", publicName: "bindLabel", isSignal: true, isRequired: false, transformFunction: null }, bindValue: { classPropertyName: "bindValue", publicName: "bindValue", isSignal: true, isRequired: false, transformFunction: null }, bindIcon: { classPropertyName: "bindIcon", publicName: "bindIcon", isSignal: true, isRequired: false, transformFunction: null }, isResponsive: { classPropertyName: "isResponsive", publicName: "isResponsive", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, notFoundText: { classPropertyName: "notFoundText", publicName: "notFoundText", isSignal: true, isRequired: false, transformFunction: null }, loadingText: { classPropertyName: "loadingText", publicName: "loadingText", isSignal: true, isRequired: false, transformFunction: null }, clearAllText: { classPropertyName: "clearAllText", publicName: "clearAllText", isSignal: true, isRequired: false, transformFunction: null }, groupBy: { classPropertyName: "groupBy", publicName: "groupBy", isSignal: true, isRequired: false, transformFunction: null }, colorKey: { classPropertyName: "colorKey", publicName: "colorKey", isSignal: true, isRequired: false, transformFunction: null }, iconAlt: { classPropertyName: "iconAlt", publicName: "iconAlt", isSignal: false, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, variation: { classPropertyName: "variation", publicName: "variation", isSignal: false, isRequired: false, transformFunction: null }, iconSrc: { classPropertyName: "iconSrc", publicName: "iconSrc", isSignal: false, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, maxLabels: { classPropertyName: "maxLabels", publicName: "maxLabels", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, allSelect: { classPropertyName: "allSelect", publicName: "allSelect", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "closeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, dropdownPosition: { classPropertyName: "dropdownPosition", publicName: "dropdownPosition", isSignal: true, isRequired: false, transformFunction: null }, hasError: { classPropertyName: "hasError", publicName: "hasError", isSignal: false, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: false, isRequired: false, transformFunction: null }, appendToBody: { classPropertyName: "appendToBody", publicName: "appendToBody", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", open: "open", close: "close", focus: "focus", blur: "blur", search: "search", clear: "clear", change: "change", scrollToEnd: "scrollToEnd" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, providers: [
|
|
5904
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkSelect, isStandalone: true, selector: "bk-select", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, bindLabel: { classPropertyName: "bindLabel", publicName: "bindLabel", isSignal: true, isRequired: false, transformFunction: null }, bindValue: { classPropertyName: "bindValue", publicName: "bindValue", isSignal: true, isRequired: false, transformFunction: null }, bindIcon: { classPropertyName: "bindIcon", publicName: "bindIcon", isSignal: true, isRequired: false, transformFunction: null }, isResponsive: { classPropertyName: "isResponsive", publicName: "isResponsive", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, notFoundText: { classPropertyName: "notFoundText", publicName: "notFoundText", isSignal: true, isRequired: false, transformFunction: null }, loadingText: { classPropertyName: "loadingText", publicName: "loadingText", isSignal: true, isRequired: false, transformFunction: null }, clearAllText: { classPropertyName: "clearAllText", publicName: "clearAllText", isSignal: true, isRequired: false, transformFunction: null }, groupBy: { classPropertyName: "groupBy", publicName: "groupBy", isSignal: true, isRequired: false, transformFunction: null }, colorKey: { classPropertyName: "colorKey", publicName: "colorKey", isSignal: true, isRequired: false, transformFunction: null }, showDots: { classPropertyName: "showDots", publicName: "showDots", isSignal: true, isRequired: false, transformFunction: null }, showAvatar: { classPropertyName: "showAvatar", publicName: "showAvatar", isSignal: true, isRequired: false, transformFunction: null }, avatarKey: { classPropertyName: "avatarKey", publicName: "avatarKey", isSignal: true, isRequired: false, transformFunction: null }, iconAlt: { classPropertyName: "iconAlt", publicName: "iconAlt", isSignal: false, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, variation: { classPropertyName: "variation", publicName: "variation", isSignal: false, isRequired: false, transformFunction: null }, iconSrc: { classPropertyName: "iconSrc", publicName: "iconSrc", isSignal: false, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, maxLabels: { classPropertyName: "maxLabels", publicName: "maxLabels", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, allSelect: { classPropertyName: "allSelect", publicName: "allSelect", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "closeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, dropdownPosition: { classPropertyName: "dropdownPosition", publicName: "dropdownPosition", isSignal: true, isRequired: false, transformFunction: null }, hasError: { classPropertyName: "hasError", publicName: "hasError", isSignal: false, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: false, isRequired: false, transformFunction: null }, appendToBody: { classPropertyName: "appendToBody", publicName: "appendToBody", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", open: "open", close: "close", focus: "focus", blur: "blur", search: "search", clear: "clear", change: "change", scrollToEnd: "scrollToEnd" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, providers: [
|
|
5510
5905
|
{
|
|
5511
5906
|
provide: NG_VALUE_ACCESSOR,
|
|
5512
5907
|
useExisting: forwardRef(() => BkSelect),
|
|
5513
5908
|
multi: true
|
|
5514
5909
|
}
|
|
5515
|
-
], viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }, { propertyName: "optionsListContainer", first: true, predicate: ["optionsListContainer"], descendants: true }, { propertyName: "controlWrapper", first: true, predicate: ["controlWrapper"], descendants: true }, { propertyName: "dropdownPanel", first: true, predicate: ["dropdownPanel"], descendants: true }, { propertyName: "chipsViewport", first: true, predicate: ["chipsViewport"], descendants: true }, { propertyName: "measurePlus", first: true, predicate: ["measurePlus"], descendants: true }, { propertyName: "optionsRef", predicate: ["optionsRef"], descendants: true }, { propertyName: "measureChips", predicate: ["measureChip"], descendants: true }], ngImport: i0, template: "<div class=\"bk-select-container\" [ngClass]=\"variation\">\r\n @if (label) {\r\n <label class=\"bk-select-label\" (click)=\"openFromLabel($event)\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"bk-select-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"relative\">\r\n <div\r\n #controlWrapper\r\n class=\"bk-select-control\"\r\n [ngClass]=\"{ 'bk-has-error': hasError }\"\r\n tabindex=\"0\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [class.bk-focused]=\"isOpen()\"\r\n [class.bk-disabled]=\"disabled()\"\r\n (mousedown)=\"toggleDropdown($event)\"\r\n >\r\n <!-- Icon (Always visible if set) -->\r\n @if (iconSrc) {\r\n <img [src]=\"iconSrc\" [alt]=\"iconAlt\" class=\"shrink-0\" />\r\n }\r\n <div class=\"bk-value-container\">\r\n @if (selectedOptions().length === 0) {\r\n <div class=\"bk-placeholder\">{{ placeholder() }}</div>\r\n }\r\n @if (multiple() && selectedOptions().length > 0) {\r\n <div #chipsViewport class=\"bk-value-chips bk-chips-viewport flex gap-0.5 flex-nowrap h-[18px] overflow-hidden\">\r\n @for (opt of selectedOptions().slice(0, visibleCount()); track $index) {\r\n <div class=\"bk-multi-badge-item me-0.5\">\r\n @if (resolveIcon(opt)) {\r\n <img [src]=\"resolveIcon(opt)!\" alt=\"icon\" class=\"bk-chip-icon shrink-0\" />\r\n }\r\n <span #badgeTextEl class=\"bk-multi-badge-item-text\" [style.color]=\"resolveColor(opt)\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(badgeTextEl, resolveLabel(opt))\"\r\n bkTooltipPosition=\"top\">{{\r\n resolveLabel(opt)\r\n }}</span>\r\n\r\n <button type=\"button\" (mousedown)=\"removeOption(opt, $event)\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"8\"\r\n height=\"8\"\r\n viewBox=\"0 0 8 8\"\r\n fill=\"none\"\r\n >\r\n <path\r\n d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\"\r\n stroke=\"#BBBDC5\"\r\n stroke-width=\"1.25\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n @if (visibleCount() < selectedOptions().length) {\r\n <div class=\"bk-multi-badge-item\">\r\n <span\r\n class=\"bk-multi-badge-item-text\"\r\n bkTooltipPosition=\"top\"\r\n [bkTooltip]=\"getRemainingItems()\"\r\n >+{{ selectedOptions().length - visibleCount() }}</span\r\n >\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Hidden off-screen row used only to measure each chip's natural\r\n width so we can decide how many fit on a single line. -->\r\n <div class=\"bk-value-chips bk-chips-measure flex gap-0.5 flex-nowrap\" aria-hidden=\"true\">\r\n @for (opt of selectedOptions(); track $index) {\r\n <div #measureChip class=\"bk-multi-badge-item me-0.5\">\r\n @if (resolveIcon(opt)) {\r\n <img [src]=\"resolveIcon(opt)!\" alt=\"icon\" class=\"bk-chip-icon shrink-0\" />\r\n }\r\n <span class=\"bk-multi-badge-item-text\">{{ resolveLabel(opt) }}</span>\r\n <button type=\"button\" tabindex=\"-1\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"8\"\r\n height=\"8\"\r\n viewBox=\"0 0 8 8\"\r\n fill=\"none\"\r\n >\r\n <path\r\n d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\"\r\n stroke=\"#BBBDC5\"\r\n stroke-width=\"1.25\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n <div #measurePlus class=\"bk-multi-badge-item\">\r\n <span class=\"bk-multi-badge-item-text\">+{{ selectedOptions().length }}</span>\r\n </div>\r\n </div>\r\n }\r\n @if (!multiple() && selectedOptions().length > 0) {\r\n <div class=\"flex items-center gap-1.5 min-w-0 w-full\">\r\n @if (resolveIcon(selectedOptions()[0])) {\r\n <img [src]=\"resolveIcon(selectedOptions()[0])!\" alt=\"icon\" class=\"bk-option-icon shrink-0\" />\r\n }\r\n <div #singleValueEl class=\"bk-value-label-single\" [style.color]=\"resolveColor(selectedOptions()[0])\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(singleValueEl, resolveLabel(selectedOptions()[0]))\"\r\n bkTooltipPosition=\"top\">\r\n {{ resolveLabel(selectedOptions()[0]) }}\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"bk-actions\">\r\n @if (clearable() && selectedOptions().length > 0 && !disabled()) {\r\n <span class=\"bk-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n </span>\r\n }\r\n <span class=\"bk-arrow-wrapper\" [class.bk-open]=\"isOpen()\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n tabindex=\"-1\"\r\n (keydown)=\"onTabPress($event)\"\r\n class=\"bk-dropdown-panel\"\r\n [attr.data-position]=\"placement()\"\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"getTop()\"\r\n [style.bottom]=\"getBottom()\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\"\r\n [style.zIndex]=\"appendToBody() ? 10000 : null\"\r\n [class.bk-grouped]=\"groupBy()\"\r\n >\r\n @if (searchable()) {\r\n <div class=\"bk-dropdown-search mb-1\">\r\n <div class=\"bk-search-wrapper\">\r\n <svg\r\n class=\"text-[#BBBDC5] mr-2\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input\r\n #searchInput\r\n tabindex=\"-1\"\r\n type=\"text\"\r\n class=\"bk-search-input\"\r\n [value]=\"searchTerm()\"\r\n [placeholder]=\"'Search...'\"\r\n (input)=\"onSearchInput($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n <div\r\n #optionsListContainer\r\n tabindex=\"-1\"\r\n class=\"bk-options-list\"\r\n [class.bk-no-responsive]=\"!isResponsive()\"\r\n (scroll)=\"onScroll($event)\"\r\n >\r\n @if (loading()) {\r\n <div class=\"bk-option-disabled\">{{ loadingText() }}</div>\r\n } @else {\r\n @if (allSelect()) {\r\n @if (multiple() && filteredItems().length > 0) {\r\n <div\r\n class=\"bk-option\"\r\n (mousedown)=\"toggleSelectAll($event)\"\r\n [class.bk-selected]=\"isAllSelected()\"\r\n >\r\n <div class=\"flex-1 flex justify-between\">\r\n <span class=\"line-clamp-1\">Select All</span>\r\n @if (isAllSelected()) {\r\n <svg\r\n class=\"text-[#141414]\"\r\n width=\"17\"\r\n height=\"17\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n >\r\n <polyline points=\"20 6 9 17 4 12\" />\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n @for (group of groupedItems(); track $index) {\r\n @if (group.group) {\r\n <div class=\"bk-option-group\">\r\n {{ group.group }}\r\n </div>\r\n }\r\n\r\n @for (item of group.items; track $index) {\r\n <div\r\n #optionsRef\r\n tabindex=\"-1\"\r\n class=\"bk-option\"\r\n [class.bk-selected]=\"isItemSelected(item)\"\r\n [class.bk-marked]=\"$index === markedIndex()\"\r\n [class.bk-option-disabled]=\"isItemDisabled(item)\"\r\n [class.cursor-not-allowed]=\"isItemDisabled(item)\"\r\n (click)=\"handleSelection(item, $event)\"\r\n (mouseenter)=\"onOptionHover($index)\"\r\n >\r\n <div class=\"flex-1 flex justify-between gap-2 min-w-0\">\r\n <div class=\"flex items-center gap-2 min-w-0 flex-1\">\r\n @if (resolveIcon(item)) {\r\n <img [src]=\"resolveIcon(item)!\" alt=\"icon\" class=\"bk-option-icon shrink-0\" />\r\n }\r\n <span #optionLabelEl class=\"bk-option-label min-w-0\" [style.color]=\"resolveColor(item)\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(optionLabelEl, resolveLabel(item))\"\r\n bkTooltipPosition=\"top\">{{\r\n resolveLabel(item)\r\n }}</span>\r\n </div>\r\n\r\n @if (isItemSelected(item)) {\r\n <svg\r\n class=\"text-[#141414] shrink-0\"\r\n width=\"17\"\r\n height=\"17\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n >\r\n <polyline points=\"20 6 9 17 4 12\" />\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @if (filteredItems().length === 0) {\r\n <div class=\"bk-option-disabled\">{{ notFoundText() }}</div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n @if (hasError) {\r\n @if (errorMessage) {\r\n <p class=\"bk-select-error\">{{ errorMessage }}</p>\r\n }\r\n }\r\n</div>\r\n", styles: [".bk-select-container{@apply relative w-full box-border flex flex-col gap-1.5;}.bk-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded cursor-pointer focus:border-[#E3E3E7] focus-visible:!outline-[.1px] focus-visible:!outline-[#6B7080];transition:border-color .2s,box-shadow .2s;box-shadow:0 1px 2px #1018280d}.bk-select-control:focus-visible{outline-style:solid!important}.bk-select-control.bk-focused{@apply border-[#6B7080] shadow-none z-10;outline:none!important}.bk-select-control.bk-disabled{@apply cursor-not-allowed;border-color:#e3e3e7;background-color:#f4f4f6}.bk-select-control.bk-disabled .bk-placeholder{color:#a1a3ae}.bk-select-container.default .bk-select-control{@apply px-3 py-2.5;}.bk-select-container.sm .bk-select-control{@apply px-3 py-[5px];}.bk-select-control.bk-has-error{@apply border-[#d11e14];}.bk-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full;}.bk-placeholder{@apply text-[#6B7080] font-normal text-[14px] truncate w-full pointer-events-none !leading-[18px];}.bk-value-label-single{@apply font-normal text-[#141414] truncate w-full;}.bk-select-container.default .bk-select-control .bk-value-label-single{@apply text-[14px] !leading-[18px];}.bk-select-container.sm .bk-select-control .bk-value-label-single{@apply text-xs;}.bk-chips-viewport{flex:1 1 0%;min-width:0;max-width:100%}.bk-chips-measure{position:absolute;top:0;left:0;visibility:hidden;pointer-events:none;white-space:nowrap;z-index:-1}.bk-multi-badge-item{@apply inline-flex items-center gap-1.5 px-1.5 py-0.5 bg-white border border-[#E3E3E7] rounded-[4px];max-width:120px;min-width:0}.bk-multi-badge-item-text{@apply text-[10px] leading-[12px] font-normal text-[#6B7080];white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bk-multi-badge-close{@apply cursor-pointer outline-none w-3 h-3;}.bk-actions{@apply flex items-center gap-0.5 flex-shrink-0;}.bk-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.bk-arrow-wrapper{@apply text-gray-400 transition-transform duration-200;}.bk-arrow-wrapper.bk-open{@apply rotate-180;}.bk-dropdown-panel{@apply absolute left-0 w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[100] overflow-hidden cursor-default p-2.5;}.bk-dropdown-search{@apply px-2 pt-2;}.bk-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.bk-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.bk-options-list{@apply overflow-y-auto overflow-x-hidden relative flex flex-col gap-0.5;}@media (max-height: 700px){.bk-options-list{max-height:125px}}@media (min-height: 701px) and (max-height: 900px){.bk-options-list{max-height:166px}}@media (min-height: 901px){.bk-options-list{max-height:210px}}.bk-options-list.bk-no-responsive{max-height:166px!important}.bk-option{@apply flex items-center p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414] min-w-0;}.bk-option:hover,.bk-option.bk-marked,.bk-option.bk-selected{@apply bg-[#F8F8F8] rounded-md;}.bk-option.bk-option-disabled{@apply opacity-50 cursor-not-allowed;}.bk-option.bk-option-disabled:hover{@apply bg-transparent;}.bk-option .bk-option-label{@apply line-clamp-1 break-all;}.bk-grouped .bk-option{@apply ps-5;}.bk-option-disabled{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}.bk-select-all-option{@apply sticky top-0 z-20 flex items-center px-3 py-2 cursor-pointer border-b border-[#E3E6EE] bg-gray-50 text-[#15191E];}.bk-select-all-option:hover{@apply bg-gray-100;}.bk-dropdown-panel[data-position=top]{margin-top:0;margin-bottom:4px}.bk-select-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] inline-block;}.bk-select-label-required{@apply text-[#E7000B];}.bk-options-list ::-webkit-scrollbar{width:10px}.bk-options-list ::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.bk-options-list ::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.bk-options-list ::-webkit-scrollbar-thumb:hover{background:#909090}.bk-option-group{@apply px-2.5 py-1 font-bold text-[13px] leading-5 text-[#141414];}.bk-option-group:not(:first-child){@apply mt-4;}.bk-select-error{@apply text-xs text-[#E7000B] font-normal;}.bk-select-hint{@apply text-xs text-[#868997] font-normal;}.bk-search-input:focus-visible{outline:2px solid transparent}.bk-option-icon{@apply w-4 h-4 object-contain rounded-sm;}.bk-chip-icon{@apply w-3 h-3 object-contain rounded-sm;}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition", "bkTooltipScrollable", "bkTooltipMaxHeight", "bkTooltipSize", "bkTooltipAutoHeight"] }] });
|
|
5910
|
+
], viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }, { propertyName: "optionsListContainer", first: true, predicate: ["optionsListContainer"], descendants: true }, { propertyName: "controlWrapper", first: true, predicate: ["controlWrapper"], descendants: true }, { propertyName: "dropdownPanel", first: true, predicate: ["dropdownPanel"], descendants: true }, { propertyName: "chipsViewport", first: true, predicate: ["chipsViewport"], descendants: true }, { propertyName: "measurePlus", first: true, predicate: ["measurePlus"], descendants: true }, { propertyName: "optionsRef", predicate: ["optionsRef"], descendants: true }, { propertyName: "measureChips", predicate: ["measureChip"], descendants: true }], ngImport: i0, template: "<div class=\"bk-select-container\" [ngClass]=\"variation\">\r\n @if (label) {\r\n <label class=\"bk-select-label\" (click)=\"openFromLabel($event)\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"bk-select-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"relative\">\r\n <!-- controlStyle() resolves the tint: the selected option's accent normally,\r\n a soft red one while hasError. It's a method rather than a computed\r\n because hasError is a plain @Input, not a signal. -->\r\n <div\r\n #controlWrapper\r\n class=\"bk-select-control\"\r\n [ngClass]=\"{ 'bk-has-error': hasError }\"\r\n tabindex=\"0\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [class.bk-focused]=\"isOpen()\"\r\n [class.bk-disabled]=\"disabled()\"\r\n [class.bk-filled]=\"!!controlStyle().backgroundColor\"\r\n [style.backgroundColor]=\"controlStyle().backgroundColor\"\r\n [style.color]=\"controlStyle().color\"\r\n [style.borderColor]=\"controlStyle().borderColor\"\r\n (mousedown)=\"toggleDropdown($event)\"\r\n >\r\n <!-- Icon (Always visible if set) -->\r\n @if (iconSrc) {\r\n <img [src]=\"iconSrc\" [alt]=\"iconAlt\" class=\"shrink-0\" />\r\n }\r\n <div class=\"bk-value-container\">\r\n @if (selectedOptions().length === 0) {\r\n <div class=\"bk-placeholder\">{{ placeholder() }}</div>\r\n }\r\n @if (multiple() && selectedOptions().length > 0) {\r\n <div\r\n #chipsViewport\r\n class=\"bk-value-chips bk-chips-viewport flex gap-0.5 flex-nowrap overflow-hidden h-[18px]\"\r\n >\r\n @for (opt of selectedOptions().slice(0, visibleCount()); track $index) {\r\n <div class=\"bk-multi-badge-item me-0.5\" [class.bk-chip-has-avatar]=\"showAvatar()\">\r\n <!-- One leading visual only: avatar > icon > dot. -->\r\n @if (showAvatar()) {\r\n <bk-avatar\r\n class=\"shrink-0 flex\"\r\n size=\"xxsm\"\r\n [src]=\"resolveAvatarSrc(opt)\"\r\n [name]=\"resolveLabel(opt)\"\r\n [alt]=\"iconAlt\"\r\n [bgColor]=\"avatarBgFor(opt)\"\r\n [textColor]=\"avatarTextFor(opt)\"\r\n ></bk-avatar>\r\n } @else if (resolveIcon(opt)) {\r\n <img [src]=\"resolveIcon(opt)!\" alt=\"icon\" class=\"bk-chip-icon shrink-0\" />\r\n } @else if (showDots() && accentFor(opt)) {\r\n <span class=\"bk-chip-dot\" [style.backgroundColor]=\"accentFor(opt)\"></span>\r\n }\r\n <span #badgeTextEl class=\"bk-multi-badge-item-text\" [style.color]=\"optionTextColor(opt)\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(badgeTextEl, resolveLabel(opt))\"\r\n bkTooltipPosition=\"top\">{{\r\n resolveLabel(opt)\r\n }}</span>\r\n\r\n <!-- A locked control must not offer a way to drop a value. -->\r\n @if (isEditable()) {\r\n <button type=\"button\" (mousedown)=\"removeOption(opt, $event)\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"8\"\r\n height=\"8\"\r\n viewBox=\"0 0 8 8\"\r\n fill=\"none\"\r\n >\r\n <path\r\n d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\"\r\n stroke=\"#BBBDC5\"\r\n stroke-width=\"1.25\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n @if (visibleCount() < selectedOptions().length) {\r\n <div class=\"bk-multi-badge-item\">\r\n <span\r\n class=\"bk-multi-badge-item-text\"\r\n bkTooltipPosition=\"top\"\r\n [bkTooltip]=\"getRemainingItems()\"\r\n >+{{ selectedOptions().length - visibleCount() }}</span\r\n >\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Hidden off-screen row used only to measure each chip's natural\r\n width so we can decide how many fit on a single line. -->\r\n <div class=\"bk-value-chips bk-chips-measure flex gap-0.5 flex-nowrap\" aria-hidden=\"true\">\r\n @for (opt of selectedOptions(); track $index) {\r\n <div #measureChip class=\"bk-multi-badge-item me-0.5\" [class.bk-chip-has-avatar]=\"showAvatar()\">\r\n <!-- Must mirror the visible chip exactly \u2014 same leading visual\r\n and same precedence \u2014 or the measured width is wrong and\r\n \"+N\" collapses at the wrong point. -->\r\n @if (showAvatar()) {\r\n <bk-avatar\r\n class=\"shrink-0 flex\"\r\n size=\"xxsm\"\r\n [src]=\"resolveAvatarSrc(opt)\"\r\n [name]=\"resolveLabel(opt)\"\r\n [alt]=\"iconAlt\"\r\n ></bk-avatar>\r\n } @else if (resolveIcon(opt)) {\r\n <img [src]=\"resolveIcon(opt)!\" alt=\"icon\" class=\"bk-chip-icon shrink-0\" />\r\n } @else if (showDots() && accentFor(opt)) {\r\n <span class=\"bk-chip-dot\"></span>\r\n }\r\n <span class=\"bk-multi-badge-item-text\">{{ resolveLabel(opt) }}</span>\r\n @if (isEditable()) {\r\n <button type=\"button\" tabindex=\"-1\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"8\"\r\n height=\"8\"\r\n viewBox=\"0 0 8 8\"\r\n fill=\"none\"\r\n >\r\n <path\r\n d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\"\r\n stroke=\"#BBBDC5\"\r\n stroke-width=\"1.25\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n <div #measurePlus class=\"bk-multi-badge-item\">\r\n <span class=\"bk-multi-badge-item-text\">+{{ selectedOptions().length }}</span>\r\n </div>\r\n </div>\r\n }\r\n @if (!multiple() && selectedOptions().length > 0) {\r\n <div class=\"flex items-center gap-1.5 min-w-0 w-full\">\r\n <!-- One leading visual only: avatar > icon > dot.\r\n `flex` on the host: bk-avatar's host is display:inline by\r\n default, so its inline-flex body sits on a baseline and the\r\n host gains descender space \u2014 which knocks the avatar out of\r\n vertical centre against the label. -->\r\n @if (showAvatar()) {\r\n <bk-avatar\r\n class=\"shrink-0 flex\"\r\n size=\"xxsm\"\r\n [src]=\"resolveAvatarSrc(selectedOptions()[0])\"\r\n [name]=\"resolveLabel(selectedOptions()[0])\"\r\n [alt]=\"iconAlt\"\r\n [bgColor]=\"avatarBgFor(selectedOptions()[0])\"\r\n [textColor]=\"avatarTextFor(selectedOptions()[0])\"\r\n ></bk-avatar>\r\n } @else if (resolveIcon(selectedOptions()[0])) {\r\n <img [src]=\"resolveIcon(selectedOptions()[0])!\" alt=\"icon\" class=\"bk-option-icon shrink-0\" />\r\n } @else if (showDots() && accentFor(selectedOptions()[0])) {\r\n <span class=\"bk-value-dot\" [style.backgroundColor]=\"accentFor(selectedOptions()[0])\"></span>\r\n }\r\n <div #singleValueEl class=\"bk-value-label-single\" [style.color]=\"controlStyle().color ?? resolveColor(selectedOptions()[0])\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(singleValueEl, resolveLabel(selectedOptions()[0]))\"\r\n bkTooltipPosition=\"top\">\r\n {{ resolveLabel(selectedOptions()[0]) }}\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"bk-actions\">\r\n @if (clearable() && selectedOptions().length > 0 && isEditable()) {\r\n <span class=\"bk-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n </span>\r\n }\r\n <span class=\"bk-arrow-wrapper\" [class.bk-open]=\"isOpen()\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n tabindex=\"-1\"\r\n (keydown)=\"onTabPress($event)\"\r\n class=\"bk-dropdown-panel\"\r\n [attr.data-position]=\"placement()\"\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"getTop()\"\r\n [style.bottom]=\"getBottom()\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\"\r\n [style.zIndex]=\"appendToBody() ? 10000 : null\"\r\n [class.bk-grouped]=\"groupBy()\"\r\n >\r\n @if (searchable()) {\r\n <div class=\"bk-dropdown-search mb-1\">\r\n <div class=\"bk-search-wrapper\">\r\n <svg\r\n class=\"text-[#BBBDC5] mr-2\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input\r\n #searchInput\r\n tabindex=\"-1\"\r\n type=\"text\"\r\n class=\"bk-search-input\"\r\n [value]=\"searchTerm()\"\r\n [placeholder]=\"'Search...'\"\r\n (input)=\"onSearchInput($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n <div\r\n #optionsListContainer\r\n tabindex=\"-1\"\r\n class=\"bk-options-list\"\r\n [class.bk-no-responsive]=\"!isResponsive()\"\r\n (scroll)=\"onScroll($event)\"\r\n >\r\n @if (loading()) {\r\n <div class=\"bk-option-disabled\">{{ loadingText() }}</div>\r\n } @else {\r\n @if (allSelect()) {\r\n @if (multiple() && filteredItems().length > 0) {\r\n <div\r\n class=\"bk-option\"\r\n (mousedown)=\"toggleSelectAll($event)\"\r\n [class.bk-selected]=\"isAllSelected()\"\r\n >\r\n <div class=\"flex-1 flex items-center gap-2 min-w-0\">\r\n <!-- Reflects state only: pointer-events-none lets the row's\r\n mousedown own the toggle, so the box can't fire twice.\r\n standalone keeps this ngModel out of any parent <form>\r\n bk-select is rendered inside. -->\r\n <bk-checkbox\r\n class=\"pointer-events-none shrink-0 flex\"\r\n checkboxClass=\"sm\"\r\n [ngModel]=\"isAllSelected()\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n ></bk-checkbox>\r\n <span class=\"line-clamp-1\">Select All</span>\r\n </div>\r\n </div>\r\n }\r\n }\r\n @for (group of groupedItems(); track $index) {\r\n @if (group.group) {\r\n <div class=\"bk-option-group\">\r\n {{ group.group }}\r\n </div>\r\n }\r\n\r\n @for (item of group.items; track $index) {\r\n <div\r\n #optionsRef\r\n tabindex=\"-1\"\r\n class=\"bk-option\"\r\n [class.bk-selected]=\"isItemSelected(item)\"\r\n [class.bk-marked]=\"$index === markedIndex()\"\r\n [class.bk-option-disabled]=\"isItemDisabled(item)\"\r\n [class.cursor-not-allowed]=\"isItemDisabled(item)\"\r\n (click)=\"handleSelection(item, $event)\"\r\n (mouseenter)=\"onOptionHover($index)\"\r\n >\r\n <div class=\"flex-1 flex justify-between gap-2 min-w-0\">\r\n <div class=\"flex items-center gap-2 min-w-0 flex-1\">\r\n <!-- One leading visual only: avatar > icon > dot. -->\r\n @if (showAvatar()) {\r\n <bk-avatar\r\n class=\"shrink-0 flex\"\r\n size=\"xxsm\"\r\n [src]=\"resolveAvatarSrc(item)\"\r\n [name]=\"resolveLabel(item)\"\r\n [alt]=\"iconAlt\"\r\n [bgColor]=\"avatarBgFor(item)\"\r\n [textColor]=\"avatarTextFor(item)\"\r\n ></bk-avatar>\r\n } @else if (resolveIcon(item)) {\r\n <img [src]=\"resolveIcon(item)!\" alt=\"icon\" class=\"bk-option-icon shrink-0\" />\r\n } @else if (showDots() && accentFor(item)) {\r\n <span class=\"bk-value-dot\" [style.backgroundColor]=\"accentFor(item)\"></span>\r\n }\r\n <span #optionLabelEl class=\"bk-option-label min-w-0\" [style.color]=\"optionTextColor(item)\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(optionLabelEl, resolveLabel(item))\"\r\n bkTooltipPosition=\"top\">{{\r\n resolveLabel(item)\r\n }}</span>\r\n </div>\r\n\r\n @if (isItemSelected(item)) {\r\n <svg\r\n class=\"text-[#141414] shrink-0\"\r\n width=\"17\"\r\n height=\"17\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n >\r\n <polyline points=\"20 6 9 17 4 12\" />\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @if (filteredItems().length === 0) {\r\n <div class=\"bk-option-disabled\">{{ notFoundText() }}</div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n @if (hasError) {\r\n @if (errorMessage) {\r\n <p class=\"bk-select-error\">{{ errorMessage }}</p>\r\n }\r\n }\r\n</div>\r\n", styles: [".bk-select-container{@apply relative w-full box-border flex flex-col gap-1.5;}.bk-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded cursor-pointer focus:border-[#E3E3E7] focus-visible:!outline-[.1px] focus-visible:!outline-[#6B7080];transition:border-color .2s,box-shadow .2s;box-shadow:0 1px 2px #1018280d}.bk-select-control:focus-visible{outline-style:solid!important}.bk-select-control.bk-focused{@apply shadow-none z-10;outline:none!important}.bk-select-control.bk-focused:not(.bk-filled){@apply border-[#6B7080];}.bk-select-control.bk-filled{box-shadow:none}.bk-select-control.bk-disabled{@apply cursor-not-allowed;border-color:#e3e3e7!important;background-color:#f4f4f6!important;color:#a1a3ae!important}.bk-select-control.bk-disabled .bk-placeholder{color:#a1a3ae}.bk-select-container.default .bk-select-control{@apply px-3 py-2.5;}.bk-select-container.sm .bk-select-control{@apply px-3 py-[5px];}.bk-select-control.bk-has-error{border-color:#d11e14!important}.bk-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full;}.bk-placeholder{@apply text-[#6B7080] font-normal text-[14px] truncate w-full pointer-events-none !leading-[18px];}.bk-value-label-single{@apply font-normal text-[#141414] truncate w-full;}.bk-select-container.default .bk-select-control .bk-value-label-single{@apply text-[14px] !leading-[18px];}.bk-select-container.sm .bk-select-control .bk-value-label-single{@apply text-xs !leading-[18px];}.bk-chips-viewport{flex:1 1 0%;min-width:0;max-width:100%}.bk-chips-measure{position:absolute;top:0;left:0;visibility:hidden;pointer-events:none;white-space:nowrap;z-index:-1}.bk-multi-badge-item{@apply inline-flex items-center gap-1.5 px-1.5 py-0.5 bg-white border border-[#E3E3E7] rounded-[4px];max-width:120px;min-width:0}.bk-multi-badge-item.bk-chip-has-avatar{@apply py-0 ps-0.5;max-width:140px}.bk-multi-badge-item-text{@apply text-[10px] leading-[12px] font-normal text-[#6B7080];white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bk-multi-badge-close{@apply cursor-pointer outline-none w-3 h-3;}.bk-actions{@apply flex items-center gap-0.5 flex-shrink-0;}.bk-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.bk-arrow-wrapper{@apply text-gray-400 transition-transform duration-200;}.bk-arrow-wrapper.bk-open{@apply rotate-180;}.bk-dropdown-panel{@apply absolute left-0 w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[100] overflow-hidden cursor-default p-2.5;}.bk-dropdown-search{@apply px-2 pt-2;}.bk-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.bk-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.bk-options-list{@apply overflow-y-auto overflow-x-hidden relative flex flex-col gap-0.5;}@media (max-height: 700px){.bk-options-list{max-height:125px}}@media (min-height: 701px) and (max-height: 900px){.bk-options-list{max-height:166px}}@media (min-height: 901px){.bk-options-list{max-height:210px}}.bk-options-list.bk-no-responsive{max-height:166px!important}.bk-option{@apply flex items-center p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414] min-w-0;}.bk-option:hover,.bk-option.bk-marked,.bk-option.bk-selected{@apply bg-[#F8F8F8] rounded-md;}.bk-option.bk-option-disabled{@apply opacity-50 cursor-not-allowed;}.bk-option.bk-option-disabled:hover{@apply bg-transparent;}.bk-option .bk-option-label{@apply line-clamp-1 break-all;}.bk-grouped .bk-option{@apply ps-5;}.bk-option-disabled{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}.bk-select-all-option{@apply sticky top-0 z-20 flex items-center px-3 py-2 cursor-pointer border-b border-[#E3E6EE] bg-gray-50 text-[#15191E];}.bk-select-all-option:hover{@apply bg-gray-100;}.bk-dropdown-panel[data-position=top]{margin-top:0;margin-bottom:4px}.bk-select-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] inline-block;}.bk-select-label-required{@apply text-[#E7000B];}.bk-options-list ::-webkit-scrollbar{width:10px}.bk-options-list ::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.bk-options-list ::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.bk-options-list ::-webkit-scrollbar-thumb:hover{background:#909090}.bk-option-group{@apply px-2.5 py-1 font-bold text-[13px] leading-5 text-[#141414];}.bk-option-group:not(:first-child){@apply mt-4;}.bk-select-error{@apply text-xs text-[#E7000B] font-normal;}.bk-select-hint{@apply text-xs text-[#868997] font-normal;}.bk-search-input:focus-visible{outline:2px solid transparent}.bk-option-icon{@apply w-4 h-4 object-contain rounded-sm;}.bk-chip-icon{@apply w-3 h-3 object-contain rounded-sm;}.bk-value-dot{@apply inline-block w-2 h-2 rounded-full shrink-0;}.bk-chip-dot{@apply inline-block w-1.5 h-1.5 rounded-full shrink-0;}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition", "bkTooltipScrollable", "bkTooltipMaxHeight", "bkTooltipSize", "bkTooltipAutoHeight"] }, { kind: "component", type: BkCheckbox, selector: "bk-checkbox", inputs: ["checkboxClass", "label", "labelClass", "disabled"], outputs: ["change"] }, { kind: "component", type: BkAvatar, selector: "bk-avatar", inputs: ["src", "alt", "name", "initialsOverride", "tooltipContent", "bgColor", "textColor", "size", "variant", "fallback", "dot", "dotPosition"], outputs: ["imageLoadError"] }] });
|
|
5516
5911
|
}
|
|
5517
5912
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkSelect, decorators: [{
|
|
5518
5913
|
type: Component,
|
|
5519
|
-
args: [{ selector: 'bk-select', standalone: true, imports: [CommonModule, FormsModule, BKTooltipDirective], providers: [
|
|
5914
|
+
args: [{ selector: 'bk-select', standalone: true, imports: [CommonModule, FormsModule, BKTooltipDirective, BkCheckbox, BkAvatar], providers: [
|
|
5520
5915
|
{
|
|
5521
5916
|
provide: NG_VALUE_ACCESSOR,
|
|
5522
5917
|
useExisting: forwardRef(() => BkSelect),
|
|
5523
5918
|
multi: true
|
|
5524
5919
|
}
|
|
5525
|
-
], template: "<div class=\"bk-select-container\" [ngClass]=\"variation\">\r\n @if (label) {\r\n <label class=\"bk-select-label\" (click)=\"openFromLabel($event)\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"bk-select-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"relative\">\r\n <div\r\n #controlWrapper\r\n class=\"bk-select-control\"\r\n [ngClass]=\"{ 'bk-has-error': hasError }\"\r\n tabindex=\"0\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [class.bk-focused]=\"isOpen()\"\r\n [class.bk-disabled]=\"disabled()\"\r\n (mousedown)=\"toggleDropdown($event)\"\r\n >\r\n <!-- Icon (Always visible if set) -->\r\n @if (iconSrc) {\r\n <img [src]=\"iconSrc\" [alt]=\"iconAlt\" class=\"shrink-0\" />\r\n }\r\n <div class=\"bk-value-container\">\r\n @if (selectedOptions().length === 0) {\r\n <div class=\"bk-placeholder\">{{ placeholder() }}</div>\r\n }\r\n @if (multiple() && selectedOptions().length > 0) {\r\n <div #chipsViewport class=\"bk-value-chips bk-chips-viewport flex gap-0.5 flex-nowrap h-[18px] overflow-hidden\">\r\n @for (opt of selectedOptions().slice(0, visibleCount()); track $index) {\r\n <div class=\"bk-multi-badge-item me-0.5\">\r\n @if (resolveIcon(opt)) {\r\n <img [src]=\"resolveIcon(opt)!\" alt=\"icon\" class=\"bk-chip-icon shrink-0\" />\r\n }\r\n <span #badgeTextEl class=\"bk-multi-badge-item-text\" [style.color]=\"resolveColor(opt)\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(badgeTextEl, resolveLabel(opt))\"\r\n bkTooltipPosition=\"top\">{{\r\n resolveLabel(opt)\r\n }}</span>\r\n\r\n <button type=\"button\" (mousedown)=\"removeOption(opt, $event)\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"8\"\r\n height=\"8\"\r\n viewBox=\"0 0 8 8\"\r\n fill=\"none\"\r\n >\r\n <path\r\n d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\"\r\n stroke=\"#BBBDC5\"\r\n stroke-width=\"1.25\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n @if (visibleCount() < selectedOptions().length) {\r\n <div class=\"bk-multi-badge-item\">\r\n <span\r\n class=\"bk-multi-badge-item-text\"\r\n bkTooltipPosition=\"top\"\r\n [bkTooltip]=\"getRemainingItems()\"\r\n >+{{ selectedOptions().length - visibleCount() }}</span\r\n >\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Hidden off-screen row used only to measure each chip's natural\r\n width so we can decide how many fit on a single line. -->\r\n <div class=\"bk-value-chips bk-chips-measure flex gap-0.5 flex-nowrap\" aria-hidden=\"true\">\r\n @for (opt of selectedOptions(); track $index) {\r\n <div #measureChip class=\"bk-multi-badge-item me-0.5\">\r\n @if (resolveIcon(opt)) {\r\n <img [src]=\"resolveIcon(opt)!\" alt=\"icon\" class=\"bk-chip-icon shrink-0\" />\r\n }\r\n <span class=\"bk-multi-badge-item-text\">{{ resolveLabel(opt) }}</span>\r\n <button type=\"button\" tabindex=\"-1\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"8\"\r\n height=\"8\"\r\n viewBox=\"0 0 8 8\"\r\n fill=\"none\"\r\n >\r\n <path\r\n d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\"\r\n stroke=\"#BBBDC5\"\r\n stroke-width=\"1.25\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n <div #measurePlus class=\"bk-multi-badge-item\">\r\n <span class=\"bk-multi-badge-item-text\">+{{ selectedOptions().length }}</span>\r\n </div>\r\n </div>\r\n }\r\n @if (!multiple() && selectedOptions().length > 0) {\r\n <div class=\"flex items-center gap-1.5 min-w-0 w-full\">\r\n @if (resolveIcon(selectedOptions()[0])) {\r\n <img [src]=\"resolveIcon(selectedOptions()[0])!\" alt=\"icon\" class=\"bk-option-icon shrink-0\" />\r\n }\r\n <div #singleValueEl class=\"bk-value-label-single\" [style.color]=\"resolveColor(selectedOptions()[0])\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(singleValueEl, resolveLabel(selectedOptions()[0]))\"\r\n bkTooltipPosition=\"top\">\r\n {{ resolveLabel(selectedOptions()[0]) }}\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"bk-actions\">\r\n @if (clearable() && selectedOptions().length > 0 && !disabled()) {\r\n <span class=\"bk-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n </span>\r\n }\r\n <span class=\"bk-arrow-wrapper\" [class.bk-open]=\"isOpen()\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n tabindex=\"-1\"\r\n (keydown)=\"onTabPress($event)\"\r\n class=\"bk-dropdown-panel\"\r\n [attr.data-position]=\"placement()\"\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"getTop()\"\r\n [style.bottom]=\"getBottom()\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\"\r\n [style.zIndex]=\"appendToBody() ? 10000 : null\"\r\n [class.bk-grouped]=\"groupBy()\"\r\n >\r\n @if (searchable()) {\r\n <div class=\"bk-dropdown-search mb-1\">\r\n <div class=\"bk-search-wrapper\">\r\n <svg\r\n class=\"text-[#BBBDC5] mr-2\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input\r\n #searchInput\r\n tabindex=\"-1\"\r\n type=\"text\"\r\n class=\"bk-search-input\"\r\n [value]=\"searchTerm()\"\r\n [placeholder]=\"'Search...'\"\r\n (input)=\"onSearchInput($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n <div\r\n #optionsListContainer\r\n tabindex=\"-1\"\r\n class=\"bk-options-list\"\r\n [class.bk-no-responsive]=\"!isResponsive()\"\r\n (scroll)=\"onScroll($event)\"\r\n >\r\n @if (loading()) {\r\n <div class=\"bk-option-disabled\">{{ loadingText() }}</div>\r\n } @else {\r\n @if (allSelect()) {\r\n @if (multiple() && filteredItems().length > 0) {\r\n <div\r\n class=\"bk-option\"\r\n (mousedown)=\"toggleSelectAll($event)\"\r\n [class.bk-selected]=\"isAllSelected()\"\r\n >\r\n <div class=\"flex-1 flex justify-between\">\r\n <span class=\"line-clamp-1\">Select All</span>\r\n @if (isAllSelected()) {\r\n <svg\r\n class=\"text-[#141414]\"\r\n width=\"17\"\r\n height=\"17\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n >\r\n <polyline points=\"20 6 9 17 4 12\" />\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n @for (group of groupedItems(); track $index) {\r\n @if (group.group) {\r\n <div class=\"bk-option-group\">\r\n {{ group.group }}\r\n </div>\r\n }\r\n\r\n @for (item of group.items; track $index) {\r\n <div\r\n #optionsRef\r\n tabindex=\"-1\"\r\n class=\"bk-option\"\r\n [class.bk-selected]=\"isItemSelected(item)\"\r\n [class.bk-marked]=\"$index === markedIndex()\"\r\n [class.bk-option-disabled]=\"isItemDisabled(item)\"\r\n [class.cursor-not-allowed]=\"isItemDisabled(item)\"\r\n (click)=\"handleSelection(item, $event)\"\r\n (mouseenter)=\"onOptionHover($index)\"\r\n >\r\n <div class=\"flex-1 flex justify-between gap-2 min-w-0\">\r\n <div class=\"flex items-center gap-2 min-w-0 flex-1\">\r\n @if (resolveIcon(item)) {\r\n <img [src]=\"resolveIcon(item)!\" alt=\"icon\" class=\"bk-option-icon shrink-0\" />\r\n }\r\n <span #optionLabelEl class=\"bk-option-label min-w-0\" [style.color]=\"resolveColor(item)\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(optionLabelEl, resolveLabel(item))\"\r\n bkTooltipPosition=\"top\">{{\r\n resolveLabel(item)\r\n }}</span>\r\n </div>\r\n\r\n @if (isItemSelected(item)) {\r\n <svg\r\n class=\"text-[#141414] shrink-0\"\r\n width=\"17\"\r\n height=\"17\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n >\r\n <polyline points=\"20 6 9 17 4 12\" />\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @if (filteredItems().length === 0) {\r\n <div class=\"bk-option-disabled\">{{ notFoundText() }}</div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n @if (hasError) {\r\n @if (errorMessage) {\r\n <p class=\"bk-select-error\">{{ errorMessage }}</p>\r\n }\r\n }\r\n</div>\r\n", styles: [".bk-select-container{@apply relative w-full box-border flex flex-col gap-1.5;}.bk-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded cursor-pointer focus:border-[#E3E3E7] focus-visible:!outline-[.1px] focus-visible:!outline-[#6B7080];transition:border-color .2s,box-shadow .2s;box-shadow:0 1px 2px #1018280d}.bk-select-control:focus-visible{outline-style:solid!important}.bk-select-control.bk-focused{@apply border-[#6B7080] shadow-none z-10;outline:none!important}.bk-select-control.bk-disabled{@apply cursor-not-allowed;border-color:#e3e3e7;background-color:#f4f4f6}.bk-select-control.bk-disabled .bk-placeholder{color:#a1a3ae}.bk-select-container.default .bk-select-control{@apply px-3 py-2.5;}.bk-select-container.sm .bk-select-control{@apply px-3 py-[5px];}.bk-select-control.bk-has-error{@apply border-[#d11e14];}.bk-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full;}.bk-placeholder{@apply text-[#6B7080] font-normal text-[14px] truncate w-full pointer-events-none !leading-[18px];}.bk-value-label-single{@apply font-normal text-[#141414] truncate w-full;}.bk-select-container.default .bk-select-control .bk-value-label-single{@apply text-[14px] !leading-[18px];}.bk-select-container.sm .bk-select-control .bk-value-label-single{@apply text-xs;}.bk-chips-viewport{flex:1 1 0%;min-width:0;max-width:100%}.bk-chips-measure{position:absolute;top:0;left:0;visibility:hidden;pointer-events:none;white-space:nowrap;z-index:-1}.bk-multi-badge-item{@apply inline-flex items-center gap-1.5 px-1.5 py-0.5 bg-white border border-[#E3E3E7] rounded-[4px];max-width:120px;min-width:0}.bk-multi-badge-item-text{@apply text-[10px] leading-[12px] font-normal text-[#6B7080];white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bk-multi-badge-close{@apply cursor-pointer outline-none w-3 h-3;}.bk-actions{@apply flex items-center gap-0.5 flex-shrink-0;}.bk-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.bk-arrow-wrapper{@apply text-gray-400 transition-transform duration-200;}.bk-arrow-wrapper.bk-open{@apply rotate-180;}.bk-dropdown-panel{@apply absolute left-0 w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[100] overflow-hidden cursor-default p-2.5;}.bk-dropdown-search{@apply px-2 pt-2;}.bk-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.bk-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.bk-options-list{@apply overflow-y-auto overflow-x-hidden relative flex flex-col gap-0.5;}@media (max-height: 700px){.bk-options-list{max-height:125px}}@media (min-height: 701px) and (max-height: 900px){.bk-options-list{max-height:166px}}@media (min-height: 901px){.bk-options-list{max-height:210px}}.bk-options-list.bk-no-responsive{max-height:166px!important}.bk-option{@apply flex items-center p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414] min-w-0;}.bk-option:hover,.bk-option.bk-marked,.bk-option.bk-selected{@apply bg-[#F8F8F8] rounded-md;}.bk-option.bk-option-disabled{@apply opacity-50 cursor-not-allowed;}.bk-option.bk-option-disabled:hover{@apply bg-transparent;}.bk-option .bk-option-label{@apply line-clamp-1 break-all;}.bk-grouped .bk-option{@apply ps-5;}.bk-option-disabled{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}.bk-select-all-option{@apply sticky top-0 z-20 flex items-center px-3 py-2 cursor-pointer border-b border-[#E3E6EE] bg-gray-50 text-[#15191E];}.bk-select-all-option:hover{@apply bg-gray-100;}.bk-dropdown-panel[data-position=top]{margin-top:0;margin-bottom:4px}.bk-select-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] inline-block;}.bk-select-label-required{@apply text-[#E7000B];}.bk-options-list ::-webkit-scrollbar{width:10px}.bk-options-list ::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.bk-options-list ::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.bk-options-list ::-webkit-scrollbar-thumb:hover{background:#909090}.bk-option-group{@apply px-2.5 py-1 font-bold text-[13px] leading-5 text-[#141414];}.bk-option-group:not(:first-child){@apply mt-4;}.bk-select-error{@apply text-xs text-[#E7000B] font-normal;}.bk-select-hint{@apply text-xs text-[#868997] font-normal;}.bk-search-input:focus-visible{outline:2px solid transparent}.bk-option-icon{@apply w-4 h-4 object-contain rounded-sm;}.bk-chip-icon{@apply w-3 h-3 object-contain rounded-sm;}\n"] }]
|
|
5526
|
-
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], bindLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindLabel", required: false }] }], bindValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindValue", required: false }] }], bindIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindIcon", required: false }] }], isResponsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "isResponsive", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], notFoundText: [{ type: i0.Input, args: [{ isSignal: true, alias: "notFoundText", required: false }] }], loadingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingText", required: false }] }], clearAllText: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearAllText", required: false }] }], groupBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupBy", required: false }] }], colorKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorKey", required: false }] }], iconAlt: [{
|
|
5920
|
+
], template: "<div class=\"bk-select-container\" [ngClass]=\"variation\">\r\n @if (label) {\r\n <label class=\"bk-select-label\" (click)=\"openFromLabel($event)\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"bk-select-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"relative\">\r\n <!-- controlStyle() resolves the tint: the selected option's accent normally,\r\n a soft red one while hasError. It's a method rather than a computed\r\n because hasError is a plain @Input, not a signal. -->\r\n <div\r\n #controlWrapper\r\n class=\"bk-select-control\"\r\n [ngClass]=\"{ 'bk-has-error': hasError }\"\r\n tabindex=\"0\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [class.bk-focused]=\"isOpen()\"\r\n [class.bk-disabled]=\"disabled()\"\r\n [class.bk-filled]=\"!!controlStyle().backgroundColor\"\r\n [style.backgroundColor]=\"controlStyle().backgroundColor\"\r\n [style.color]=\"controlStyle().color\"\r\n [style.borderColor]=\"controlStyle().borderColor\"\r\n (mousedown)=\"toggleDropdown($event)\"\r\n >\r\n <!-- Icon (Always visible if set) -->\r\n @if (iconSrc) {\r\n <img [src]=\"iconSrc\" [alt]=\"iconAlt\" class=\"shrink-0\" />\r\n }\r\n <div class=\"bk-value-container\">\r\n @if (selectedOptions().length === 0) {\r\n <div class=\"bk-placeholder\">{{ placeholder() }}</div>\r\n }\r\n @if (multiple() && selectedOptions().length > 0) {\r\n <div\r\n #chipsViewport\r\n class=\"bk-value-chips bk-chips-viewport flex gap-0.5 flex-nowrap overflow-hidden h-[18px]\"\r\n >\r\n @for (opt of selectedOptions().slice(0, visibleCount()); track $index) {\r\n <div class=\"bk-multi-badge-item me-0.5\" [class.bk-chip-has-avatar]=\"showAvatar()\">\r\n <!-- One leading visual only: avatar > icon > dot. -->\r\n @if (showAvatar()) {\r\n <bk-avatar\r\n class=\"shrink-0 flex\"\r\n size=\"xxsm\"\r\n [src]=\"resolveAvatarSrc(opt)\"\r\n [name]=\"resolveLabel(opt)\"\r\n [alt]=\"iconAlt\"\r\n [bgColor]=\"avatarBgFor(opt)\"\r\n [textColor]=\"avatarTextFor(opt)\"\r\n ></bk-avatar>\r\n } @else if (resolveIcon(opt)) {\r\n <img [src]=\"resolveIcon(opt)!\" alt=\"icon\" class=\"bk-chip-icon shrink-0\" />\r\n } @else if (showDots() && accentFor(opt)) {\r\n <span class=\"bk-chip-dot\" [style.backgroundColor]=\"accentFor(opt)\"></span>\r\n }\r\n <span #badgeTextEl class=\"bk-multi-badge-item-text\" [style.color]=\"optionTextColor(opt)\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(badgeTextEl, resolveLabel(opt))\"\r\n bkTooltipPosition=\"top\">{{\r\n resolveLabel(opt)\r\n }}</span>\r\n\r\n <!-- A locked control must not offer a way to drop a value. -->\r\n @if (isEditable()) {\r\n <button type=\"button\" (mousedown)=\"removeOption(opt, $event)\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"8\"\r\n height=\"8\"\r\n viewBox=\"0 0 8 8\"\r\n fill=\"none\"\r\n >\r\n <path\r\n d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\"\r\n stroke=\"#BBBDC5\"\r\n stroke-width=\"1.25\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n @if (visibleCount() < selectedOptions().length) {\r\n <div class=\"bk-multi-badge-item\">\r\n <span\r\n class=\"bk-multi-badge-item-text\"\r\n bkTooltipPosition=\"top\"\r\n [bkTooltip]=\"getRemainingItems()\"\r\n >+{{ selectedOptions().length - visibleCount() }}</span\r\n >\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Hidden off-screen row used only to measure each chip's natural\r\n width so we can decide how many fit on a single line. -->\r\n <div class=\"bk-value-chips bk-chips-measure flex gap-0.5 flex-nowrap\" aria-hidden=\"true\">\r\n @for (opt of selectedOptions(); track $index) {\r\n <div #measureChip class=\"bk-multi-badge-item me-0.5\" [class.bk-chip-has-avatar]=\"showAvatar()\">\r\n <!-- Must mirror the visible chip exactly \u2014 same leading visual\r\n and same precedence \u2014 or the measured width is wrong and\r\n \"+N\" collapses at the wrong point. -->\r\n @if (showAvatar()) {\r\n <bk-avatar\r\n class=\"shrink-0 flex\"\r\n size=\"xxsm\"\r\n [src]=\"resolveAvatarSrc(opt)\"\r\n [name]=\"resolveLabel(opt)\"\r\n [alt]=\"iconAlt\"\r\n ></bk-avatar>\r\n } @else if (resolveIcon(opt)) {\r\n <img [src]=\"resolveIcon(opt)!\" alt=\"icon\" class=\"bk-chip-icon shrink-0\" />\r\n } @else if (showDots() && accentFor(opt)) {\r\n <span class=\"bk-chip-dot\"></span>\r\n }\r\n <span class=\"bk-multi-badge-item-text\">{{ resolveLabel(opt) }}</span>\r\n @if (isEditable()) {\r\n <button type=\"button\" tabindex=\"-1\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"8\"\r\n height=\"8\"\r\n viewBox=\"0 0 8 8\"\r\n fill=\"none\"\r\n >\r\n <path\r\n d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\"\r\n stroke=\"#BBBDC5\"\r\n stroke-width=\"1.25\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n <div #measurePlus class=\"bk-multi-badge-item\">\r\n <span class=\"bk-multi-badge-item-text\">+{{ selectedOptions().length }}</span>\r\n </div>\r\n </div>\r\n }\r\n @if (!multiple() && selectedOptions().length > 0) {\r\n <div class=\"flex items-center gap-1.5 min-w-0 w-full\">\r\n <!-- One leading visual only: avatar > icon > dot.\r\n `flex` on the host: bk-avatar's host is display:inline by\r\n default, so its inline-flex body sits on a baseline and the\r\n host gains descender space \u2014 which knocks the avatar out of\r\n vertical centre against the label. -->\r\n @if (showAvatar()) {\r\n <bk-avatar\r\n class=\"shrink-0 flex\"\r\n size=\"xxsm\"\r\n [src]=\"resolveAvatarSrc(selectedOptions()[0])\"\r\n [name]=\"resolveLabel(selectedOptions()[0])\"\r\n [alt]=\"iconAlt\"\r\n [bgColor]=\"avatarBgFor(selectedOptions()[0])\"\r\n [textColor]=\"avatarTextFor(selectedOptions()[0])\"\r\n ></bk-avatar>\r\n } @else if (resolveIcon(selectedOptions()[0])) {\r\n <img [src]=\"resolveIcon(selectedOptions()[0])!\" alt=\"icon\" class=\"bk-option-icon shrink-0\" />\r\n } @else if (showDots() && accentFor(selectedOptions()[0])) {\r\n <span class=\"bk-value-dot\" [style.backgroundColor]=\"accentFor(selectedOptions()[0])\"></span>\r\n }\r\n <div #singleValueEl class=\"bk-value-label-single\" [style.color]=\"controlStyle().color ?? resolveColor(selectedOptions()[0])\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(singleValueEl, resolveLabel(selectedOptions()[0]))\"\r\n bkTooltipPosition=\"top\">\r\n {{ resolveLabel(selectedOptions()[0]) }}\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"bk-actions\">\r\n @if (clearable() && selectedOptions().length > 0 && isEditable()) {\r\n <span class=\"bk-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n </span>\r\n }\r\n <span class=\"bk-arrow-wrapper\" [class.bk-open]=\"isOpen()\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"18\"\r\n height=\"18\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <path d=\"m6 9 6 6 6-6\" />\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n tabindex=\"-1\"\r\n (keydown)=\"onTabPress($event)\"\r\n class=\"bk-dropdown-panel\"\r\n [attr.data-position]=\"placement()\"\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"getTop()\"\r\n [style.bottom]=\"getBottom()\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\"\r\n [style.zIndex]=\"appendToBody() ? 10000 : null\"\r\n [class.bk-grouped]=\"groupBy()\"\r\n >\r\n @if (searchable()) {\r\n <div class=\"bk-dropdown-search mb-1\">\r\n <div class=\"bk-search-wrapper\">\r\n <svg\r\n class=\"text-[#BBBDC5] mr-2\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input\r\n #searchInput\r\n tabindex=\"-1\"\r\n type=\"text\"\r\n class=\"bk-search-input\"\r\n [value]=\"searchTerm()\"\r\n [placeholder]=\"'Search...'\"\r\n (input)=\"onSearchInput($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n <div\r\n #optionsListContainer\r\n tabindex=\"-1\"\r\n class=\"bk-options-list\"\r\n [class.bk-no-responsive]=\"!isResponsive()\"\r\n (scroll)=\"onScroll($event)\"\r\n >\r\n @if (loading()) {\r\n <div class=\"bk-option-disabled\">{{ loadingText() }}</div>\r\n } @else {\r\n @if (allSelect()) {\r\n @if (multiple() && filteredItems().length > 0) {\r\n <div\r\n class=\"bk-option\"\r\n (mousedown)=\"toggleSelectAll($event)\"\r\n [class.bk-selected]=\"isAllSelected()\"\r\n >\r\n <div class=\"flex-1 flex items-center gap-2 min-w-0\">\r\n <!-- Reflects state only: pointer-events-none lets the row's\r\n mousedown own the toggle, so the box can't fire twice.\r\n standalone keeps this ngModel out of any parent <form>\r\n bk-select is rendered inside. -->\r\n <bk-checkbox\r\n class=\"pointer-events-none shrink-0 flex\"\r\n checkboxClass=\"sm\"\r\n [ngModel]=\"isAllSelected()\"\r\n [ngModelOptions]=\"{ standalone: true }\"\r\n ></bk-checkbox>\r\n <span class=\"line-clamp-1\">Select All</span>\r\n </div>\r\n </div>\r\n }\r\n }\r\n @for (group of groupedItems(); track $index) {\r\n @if (group.group) {\r\n <div class=\"bk-option-group\">\r\n {{ group.group }}\r\n </div>\r\n }\r\n\r\n @for (item of group.items; track $index) {\r\n <div\r\n #optionsRef\r\n tabindex=\"-1\"\r\n class=\"bk-option\"\r\n [class.bk-selected]=\"isItemSelected(item)\"\r\n [class.bk-marked]=\"$index === markedIndex()\"\r\n [class.bk-option-disabled]=\"isItemDisabled(item)\"\r\n [class.cursor-not-allowed]=\"isItemDisabled(item)\"\r\n (click)=\"handleSelection(item, $event)\"\r\n (mouseenter)=\"onOptionHover($index)\"\r\n >\r\n <div class=\"flex-1 flex justify-between gap-2 min-w-0\">\r\n <div class=\"flex items-center gap-2 min-w-0 flex-1\">\r\n <!-- One leading visual only: avatar > icon > dot. -->\r\n @if (showAvatar()) {\r\n <bk-avatar\r\n class=\"shrink-0 flex\"\r\n size=\"xxsm\"\r\n [src]=\"resolveAvatarSrc(item)\"\r\n [name]=\"resolveLabel(item)\"\r\n [alt]=\"iconAlt\"\r\n [bgColor]=\"avatarBgFor(item)\"\r\n [textColor]=\"avatarTextFor(item)\"\r\n ></bk-avatar>\r\n } @else if (resolveIcon(item)) {\r\n <img [src]=\"resolveIcon(item)!\" alt=\"icon\" class=\"bk-option-icon shrink-0\" />\r\n } @else if (showDots() && accentFor(item)) {\r\n <span class=\"bk-value-dot\" [style.backgroundColor]=\"accentFor(item)\"></span>\r\n }\r\n <span #optionLabelEl class=\"bk-option-label min-w-0\" [style.color]=\"optionTextColor(item)\"\r\n [bkTooltip]=\"getTooltipIfEllipsed(optionLabelEl, resolveLabel(item))\"\r\n bkTooltipPosition=\"top\">{{\r\n resolveLabel(item)\r\n }}</span>\r\n </div>\r\n\r\n @if (isItemSelected(item)) {\r\n <svg\r\n class=\"text-[#141414] shrink-0\"\r\n width=\"17\"\r\n height=\"17\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n >\r\n <polyline points=\"20 6 9 17 4 12\" />\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n\r\n @if (filteredItems().length === 0) {\r\n <div class=\"bk-option-disabled\">{{ notFoundText() }}</div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n @if (hasError) {\r\n @if (errorMessage) {\r\n <p class=\"bk-select-error\">{{ errorMessage }}</p>\r\n }\r\n }\r\n</div>\r\n", styles: [".bk-select-container{@apply relative w-full box-border flex flex-col gap-1.5;}.bk-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded cursor-pointer focus:border-[#E3E3E7] focus-visible:!outline-[.1px] focus-visible:!outline-[#6B7080];transition:border-color .2s,box-shadow .2s;box-shadow:0 1px 2px #1018280d}.bk-select-control:focus-visible{outline-style:solid!important}.bk-select-control.bk-focused{@apply shadow-none z-10;outline:none!important}.bk-select-control.bk-focused:not(.bk-filled){@apply border-[#6B7080];}.bk-select-control.bk-filled{box-shadow:none}.bk-select-control.bk-disabled{@apply cursor-not-allowed;border-color:#e3e3e7!important;background-color:#f4f4f6!important;color:#a1a3ae!important}.bk-select-control.bk-disabled .bk-placeholder{color:#a1a3ae}.bk-select-container.default .bk-select-control{@apply px-3 py-2.5;}.bk-select-container.sm .bk-select-control{@apply px-3 py-[5px];}.bk-select-control.bk-has-error{border-color:#d11e14!important}.bk-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full;}.bk-placeholder{@apply text-[#6B7080] font-normal text-[14px] truncate w-full pointer-events-none !leading-[18px];}.bk-value-label-single{@apply font-normal text-[#141414] truncate w-full;}.bk-select-container.default .bk-select-control .bk-value-label-single{@apply text-[14px] !leading-[18px];}.bk-select-container.sm .bk-select-control .bk-value-label-single{@apply text-xs !leading-[18px];}.bk-chips-viewport{flex:1 1 0%;min-width:0;max-width:100%}.bk-chips-measure{position:absolute;top:0;left:0;visibility:hidden;pointer-events:none;white-space:nowrap;z-index:-1}.bk-multi-badge-item{@apply inline-flex items-center gap-1.5 px-1.5 py-0.5 bg-white border border-[#E3E3E7] rounded-[4px];max-width:120px;min-width:0}.bk-multi-badge-item.bk-chip-has-avatar{@apply py-0 ps-0.5;max-width:140px}.bk-multi-badge-item-text{@apply text-[10px] leading-[12px] font-normal text-[#6B7080];white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bk-multi-badge-close{@apply cursor-pointer outline-none w-3 h-3;}.bk-actions{@apply flex items-center gap-0.5 flex-shrink-0;}.bk-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.bk-arrow-wrapper{@apply text-gray-400 transition-transform duration-200;}.bk-arrow-wrapper.bk-open{@apply rotate-180;}.bk-dropdown-panel{@apply absolute left-0 w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[100] overflow-hidden cursor-default p-2.5;}.bk-dropdown-search{@apply px-2 pt-2;}.bk-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.bk-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.bk-options-list{@apply overflow-y-auto overflow-x-hidden relative flex flex-col gap-0.5;}@media (max-height: 700px){.bk-options-list{max-height:125px}}@media (min-height: 701px) and (max-height: 900px){.bk-options-list{max-height:166px}}@media (min-height: 901px){.bk-options-list{max-height:210px}}.bk-options-list.bk-no-responsive{max-height:166px!important}.bk-option{@apply flex items-center p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414] min-w-0;}.bk-option:hover,.bk-option.bk-marked,.bk-option.bk-selected{@apply bg-[#F8F8F8] rounded-md;}.bk-option.bk-option-disabled{@apply opacity-50 cursor-not-allowed;}.bk-option.bk-option-disabled:hover{@apply bg-transparent;}.bk-option .bk-option-label{@apply line-clamp-1 break-all;}.bk-grouped .bk-option{@apply ps-5;}.bk-option-disabled{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}.bk-select-all-option{@apply sticky top-0 z-20 flex items-center px-3 py-2 cursor-pointer border-b border-[#E3E6EE] bg-gray-50 text-[#15191E];}.bk-select-all-option:hover{@apply bg-gray-100;}.bk-dropdown-panel[data-position=top]{margin-top:0;margin-bottom:4px}.bk-select-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] inline-block;}.bk-select-label-required{@apply text-[#E7000B];}.bk-options-list ::-webkit-scrollbar{width:10px}.bk-options-list ::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.bk-options-list ::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.bk-options-list ::-webkit-scrollbar-thumb:hover{background:#909090}.bk-option-group{@apply px-2.5 py-1 font-bold text-[13px] leading-5 text-[#141414];}.bk-option-group:not(:first-child){@apply mt-4;}.bk-select-error{@apply text-xs text-[#E7000B] font-normal;}.bk-select-hint{@apply text-xs text-[#868997] font-normal;}.bk-search-input:focus-visible{outline:2px solid transparent}.bk-option-icon{@apply w-4 h-4 object-contain rounded-sm;}.bk-chip-icon{@apply w-3 h-3 object-contain rounded-sm;}.bk-value-dot{@apply inline-block w-2 h-2 rounded-full shrink-0;}.bk-chip-dot{@apply inline-block w-1.5 h-1.5 rounded-full shrink-0;}\n"] }]
|
|
5921
|
+
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], bindLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindLabel", required: false }] }], bindValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindValue", required: false }] }], bindIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindIcon", required: false }] }], isResponsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "isResponsive", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], notFoundText: [{ type: i0.Input, args: [{ isSignal: true, alias: "notFoundText", required: false }] }], loadingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingText", required: false }] }], clearAllText: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearAllText", required: false }] }], groupBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupBy", required: false }] }], colorKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorKey", required: false }] }], showDots: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDots", required: false }] }], showAvatar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAvatar", required: false }] }], avatarKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarKey", required: false }] }], iconAlt: [{
|
|
5527
5922
|
type: Input
|
|
5528
5923
|
}], label: [{
|
|
5529
5924
|
type: Input
|
|
@@ -7920,6 +8315,17 @@ class BkHierarchicalSelect {
|
|
|
7920
8315
|
colorKey = input('', ...(ngDevMode ? [{ debugName: "colorKey" }] : []));
|
|
7921
8316
|
/** Whether to show clear button when a value is selected. */
|
|
7922
8317
|
clearable = input(true, ...(ngDevMode ? [{ debugName: "clearable" }] : []));
|
|
8318
|
+
/**
|
|
8319
|
+
* Show an accent dot beside each option, driven by `colorKey`, and tint the
|
|
8320
|
+
* control with the selected node's colour (same treatment as bk-status-select).
|
|
8321
|
+
*/
|
|
8322
|
+
showDots = input(false, ...(ngDevMode ? [{ debugName: "showDots" }] : []));
|
|
8323
|
+
/**
|
|
8324
|
+
* When true, a child with no colour of its own borrows its nearest coloured
|
|
8325
|
+
* ancestor's, keeping a branch visually related. Off by default so existing
|
|
8326
|
+
* trees render exactly as before.
|
|
8327
|
+
*/
|
|
8328
|
+
inheritColor = input(false, ...(ngDevMode ? [{ debugName: "inheritColor" }] : []));
|
|
7923
8329
|
/** Optional anchor key to scope dropdown to one subtree (e.g. module/category key). */
|
|
7924
8330
|
restrictKey = input(null, ...(ngDevMode ? [{ debugName: "restrictKey" }] : []));
|
|
7925
8331
|
hasError = input(false, ...(ngDevMode ? [{ debugName: "hasError" }] : []));
|
|
@@ -8108,14 +8514,59 @@ class BkHierarchicalSelect {
|
|
|
8108
8514
|
const key = this.colorKey();
|
|
8109
8515
|
return key && typeof node === 'object' ? node[key] ?? null : null;
|
|
8110
8516
|
}
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8517
|
+
/**
|
|
8518
|
+
* Accent for the last node of a root→node path: its own colour, or — when
|
|
8519
|
+
* `inheritColor` is on — the nearest coloured ancestor's.
|
|
8520
|
+
*/
|
|
8521
|
+
colorAlong(path) {
|
|
8522
|
+
if (!path.length)
|
|
8523
|
+
return null;
|
|
8524
|
+
if (!this.inheritColor())
|
|
8525
|
+
return this.resolveColor(path[path.length - 1]);
|
|
8526
|
+
for (let i = path.length - 1; i >= 0; i--) {
|
|
8527
|
+
const color = this.resolveColor(path[i]);
|
|
8528
|
+
if (color)
|
|
8529
|
+
return color;
|
|
8530
|
+
}
|
|
8531
|
+
return null;
|
|
8114
8532
|
}
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8533
|
+
/** Accent for a row in the level on screen — its ancestors are the breadcrumb. */
|
|
8534
|
+
optionAccentColor(node) {
|
|
8535
|
+
return this.colorAlong([...this.breadcrumb(), node]);
|
|
8536
|
+
}
|
|
8537
|
+
/**
|
|
8538
|
+
* Colours for the control itself, from the selected node. Neutral unless
|
|
8539
|
+
* `showDots` is on, so existing usages are untouched.
|
|
8540
|
+
*/
|
|
8541
|
+
controlAppearance = computed(() => {
|
|
8542
|
+
if (!this.showDots())
|
|
8543
|
+
return NEUTRAL_APPEARANCE;
|
|
8544
|
+
const sel = this.selected();
|
|
8545
|
+
if (!sel)
|
|
8546
|
+
return NEUTRAL_APPEARANCE;
|
|
8547
|
+
return deriveAppearance(this.colorAlong(this.buildPathTo(sel)), 'subtle');
|
|
8548
|
+
}, ...(ngDevMode ? [{ debugName: "controlAppearance" }] : []));
|
|
8549
|
+
/** Raw accent for a node's dot. */
|
|
8550
|
+
accentFor(node) {
|
|
8551
|
+
return deriveAppearance(this.optionAccentColor(node), 'subtle').dotColor;
|
|
8552
|
+
}
|
|
8553
|
+
/**
|
|
8554
|
+
* Label colour for an option. With showDots on, the accent is darkened until
|
|
8555
|
+
* legible; otherwise the raw colorKey value is used as before.
|
|
8556
|
+
*/
|
|
8557
|
+
optionTextColor(node) {
|
|
8558
|
+
if (!this.showDots())
|
|
8559
|
+
return this.resolveColor(node);
|
|
8560
|
+
return deriveAppearance(this.optionAccentColor(node), 'none').color;
|
|
8561
|
+
}
|
|
8562
|
+
getValue(node) {
|
|
8563
|
+
const key = this.valueKey();
|
|
8564
|
+
return key && node ? node[key] : node;
|
|
8565
|
+
}
|
|
8566
|
+
getChildren(node) {
|
|
8567
|
+
const key = this.childrenKey();
|
|
8568
|
+
const raw = node?.[key];
|
|
8569
|
+
if (Array.isArray(raw) && raw.length > 0)
|
|
8119
8570
|
return raw;
|
|
8120
8571
|
const alt = node?.['children'];
|
|
8121
8572
|
return Array.isArray(alt) && alt.length > 0 ? alt : undefined;
|
|
@@ -8381,13 +8832,13 @@ class BkHierarchicalSelect {
|
|
|
8381
8832
|
this.clear.emit(null);
|
|
8382
8833
|
}
|
|
8383
8834
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkHierarchicalSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8384
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkHierarchicalSelect, isStandalone: true, selector: "bk-hierarchical-select", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, labelKey: { classPropertyName: "labelKey", publicName: "labelKey", isSignal: true, isRequired: false, transformFunction: null }, valueKey: { classPropertyName: "valueKey", publicName: "valueKey", isSignal: true, isRequired: false, transformFunction: null }, childrenKey: { classPropertyName: "childrenKey", publicName: "childrenKey", isSignal: true, isRequired: false, transformFunction: null }, clearTooltip: { classPropertyName: "clearTooltip", publicName: "clearTooltip", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, iconSrc: { classPropertyName: "iconSrc", publicName: "iconSrc", isSignal: true, isRequired: false, transformFunction: null }, iconAlt: { classPropertyName: "iconAlt", publicName: "iconAlt", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, allowParentSelection: { classPropertyName: "allowParentSelection", publicName: "allowParentSelection", isSignal: true, isRequired: false, transformFunction: null }, backToMainText: { classPropertyName: "backToMainText", publicName: "backToMainText", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, appendToBody: { classPropertyName: "appendToBody", publicName: "appendToBody", isSignal: true, isRequired: false, transformFunction: null }, dropdownPosition: { classPropertyName: "dropdownPosition", publicName: "dropdownPosition", isSignal: true, isRequired: false, transformFunction: null }, colorKey: { classPropertyName: "colorKey", publicName: "colorKey", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, restrictKey: { classPropertyName: "restrictKey", publicName: "restrictKey", isSignal: true, isRequired: false, transformFunction: null }, hasError: { classPropertyName: "hasError", publicName: "hasError", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", valueChange: "valueChange", clear: "clear" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, providers: [
|
|
8835
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkHierarchicalSelect, isStandalone: true, selector: "bk-hierarchical-select", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, labelKey: { classPropertyName: "labelKey", publicName: "labelKey", isSignal: true, isRequired: false, transformFunction: null }, valueKey: { classPropertyName: "valueKey", publicName: "valueKey", isSignal: true, isRequired: false, transformFunction: null }, childrenKey: { classPropertyName: "childrenKey", publicName: "childrenKey", isSignal: true, isRequired: false, transformFunction: null }, clearTooltip: { classPropertyName: "clearTooltip", publicName: "clearTooltip", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, iconSrc: { classPropertyName: "iconSrc", publicName: "iconSrc", isSignal: true, isRequired: false, transformFunction: null }, iconAlt: { classPropertyName: "iconAlt", publicName: "iconAlt", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, allowParentSelection: { classPropertyName: "allowParentSelection", publicName: "allowParentSelection", isSignal: true, isRequired: false, transformFunction: null }, backToMainText: { classPropertyName: "backToMainText", publicName: "backToMainText", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, appendToBody: { classPropertyName: "appendToBody", publicName: "appendToBody", isSignal: true, isRequired: false, transformFunction: null }, dropdownPosition: { classPropertyName: "dropdownPosition", publicName: "dropdownPosition", isSignal: true, isRequired: false, transformFunction: null }, colorKey: { classPropertyName: "colorKey", publicName: "colorKey", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, showDots: { classPropertyName: "showDots", publicName: "showDots", isSignal: true, isRequired: false, transformFunction: null }, inheritColor: { classPropertyName: "inheritColor", publicName: "inheritColor", isSignal: true, isRequired: false, transformFunction: null }, restrictKey: { classPropertyName: "restrictKey", publicName: "restrictKey", isSignal: true, isRequired: false, transformFunction: null }, hasError: { classPropertyName: "hasError", publicName: "hasError", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", valueChange: "valueChange", clear: "clear" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, providers: [
|
|
8385
8836
|
{
|
|
8386
8837
|
provide: NG_VALUE_ACCESSOR,
|
|
8387
8838
|
useExisting: forwardRef(() => BkHierarchicalSelect),
|
|
8388
8839
|
multi: true,
|
|
8389
8840
|
},
|
|
8390
|
-
], viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }, { propertyName: "controlWrapper", first: true, predicate: ["controlWrapper"], descendants: true }, { propertyName: "dropdownPanel", first: true, predicate: ["dropdownPanel"], descendants: true }], ngImport: i0, template: "<div class=\"hierarchical-select-container\">\r\n @if (label()) {\r\n <label\r\n class=\"input-label\"\r\n (click)=\"openFromLabel($event)\">\r\n {{ label() }}\r\n @if (required()) {\r\n <span class=\"input-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"hierarchical-select-field\">\r\n <div\r\n #controlWrapper\r\n class=\"hierarchical-select-control\"\r\n [ngClass]=\"{ 'hierarchical-select-control-has-error': hasError() }\"\r\n tabindex=\"0\"\r\n [class.focused]=\"isOpen()\"\r\n [class.disabled]=\"isDisabled()\"\r\n (mousedown)=\"toggleDropdown($event)\">\r\n @if (iconSrc()) {\r\n <img [src]=\"iconSrc()\" [alt]=\"iconAlt()\" class=\"shrink-0\" />\r\n }\r\n <div class=\"hierarchical-value-container\">\r\n @if (!selected()) {\r\n <div class=\"hierarchical-placeholder\">{{ placeholder() }}</div>\r\n } @else {\r\n <div class=\"hierarchical-value-label\" [style.color]=\"resolveColor(selected())\">\r\n @for (node of displayPath(); track getValue(node); let last = $last) {\r\n <span\r\n #breadNode\r\n class=\"hierarchical-breadcrumb-node\"\r\n [bkTooltip]=\"breadNode.scrollWidth > breadNode.clientWidth ? getLabel(node) : ''\"\r\n bkTooltipPosition=\"top\">{{ getLabel(node) }}</span>\r\n\r\n @if (!last) {\r\n <svg\r\n class=\"breadcrumb-separator\"\r\n width=\"5\"\r\n height=\"8\"\r\n viewBox=\"0 0 5 8\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M4.57142 4.00286C4.57185 3.92766 4.55744 3.85312 4.52901 3.78351C4.50057 3.71389 4.45868 3.65058 4.40572 3.59719L0.977497 0.169008C0.924381 0.115455 0.861186 0.0729493 0.79156 0.0439419C0.721933 0.0149346 0.647251 0 0.571824 0C0.496396 0 0.421714 0.0149346 0.352088 0.0439419C0.282461 0.0729493 0.219267 0.115455 0.16615 0.169008C0.059732 0.27606 0 0.420874 0 0.57182C0 0.722766 0.059732 0.867579 0.16615 0.974631L3.19442 4.00286L0.16615 7.02537C0.059732 7.13242 0 7.27723 0 7.42818C0 7.57913 0.059732 7.72394 0.16615 7.83099C0.219267 7.88454 0.282461 7.92705 0.352088 7.95606C0.421714 7.98507 0.496396 8 0.571824 8C0.647251 8 0.721933 7.98507 0.79156 7.95606C0.861186 7.92705 0.924381 7.88454 0.977497 7.83099L4.40572 4.40281C4.51128 4.29639 4.57079 4.15275 4.57142 4.00286Z\"\r\n fill=\"#BBBDC5\"/>\r\n </svg>\r\n }\r\n }\r\n </div>\r\n\r\n }\r\n </div>\r\n <div class=\"hierarchical-actions\">\r\n @if (clearable() && selected() && !isDisabled()) {\r\n <span class=\"hierarchical-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\" [bkTooltip]=\"clearTooltip()\" bkTooltipPosition=\"top\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n </span>\r\n }\r\n <span class=\"hierarchical-arrow\" [class.open]=\"isOpen()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"m6 9 6 6 6-6\"/>\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n class=\"hierarchical-dropdown-panel\"\r\n [attr.data-position]=\"placement()\"\r\n [class.hierarchical-dropdown-panel-fixed]=\"appendToBody()\"\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"appendToBody() ? getTop() : null\"\r\n [style.bottom]=\"appendToBody() ? getBottom() : null\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\">\r\n @if (searchable()) {\r\n <div class=\"hierarchical-search\">\r\n <div class=\"hierarchical-search-wrapper\">\r\n <svg class=\"text-[#BBBDC5] mr-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\">\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input\r\n #searchInput\r\n type=\"text\"\r\n class=\"hierarchical-search-input\"\r\n [value]=\"searchTerm()\"\r\n [placeholder]=\"searchPlaceholder()\"\r\n (input)=\"onSearchInput($event)\"\r\n (click)=\"$event.stopPropagation()\" />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (showBack()) {\r\n <button\r\n type=\"button\"\r\n class=\"hierarchical-back\"\r\n (click)=\"goBack(); $event.stopPropagation()\">\r\n <span>\r\n <svg width=\"6\" height=\"10\" viewBox=\"0 0 6 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n<path d=\"M4.59961 0.599976L0.599609 4.59998L4.59961 8.59998\" stroke=\"#141414\" stroke-width=\"1.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n</svg>\r\n\r\n </span>\r\n {{ backToMainText() }}\r\n </button>\r\n }\r\n\r\n <div class=\"hierarchical-options-list\">\r\n @for (item of filteredItems(); track getValue(item)) {\r\n <div\r\n class=\"hierarchical-option\"\r\n [class.selected]=\"isSelected(item)\"\r\n [class.disabled-item]=\"item.disabled\"\r\n [class.cursor-not-allowed]=\"item.disabled\"\r\n (mousedown)=\"selectItem(item, $event)\">\r\n <span\r\n #optLabel\r\n class=\"hierarchical-option-label\"\r\n [style.color]=\"resolveColor(item)\"\r\n [bkTooltip]=\"optLabel.scrollWidth > optLabel.clientWidth ? getLabel(item) : ''\"\r\n bkTooltipPosition=\"top\">{{ getLabel(item) }}</span>\r\n @if (hasChildren(item)) {\r\n <svg width=\"5\" height=\"8\" viewBox=\"0 0 5 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M4.57142 4.00286C4.57185 3.92766 4.55744 3.85312 4.52901 3.78351C4.50057 3.71389 4.45868 3.65058 4.40572 3.59719L0.977497 0.169008C0.924381 0.115455 0.861186 0.0729493 0.79156 0.0439419C0.721933 0.0149346 0.647251 0 0.571824 0C0.496396 0 0.421714 0.0149346 0.352088 0.0439419C0.282461 0.0729493 0.219267 0.115455 0.16615 0.169008C0.059732 0.27606 0 0.420874 0 0.57182C0 0.722766 0.059732 0.867579 0.16615 0.974631L3.19442 4.00286L0.16615 7.02537C0.059732 7.13242 0 7.27723 0 7.42818C0 7.57913 0.059732 7.72394 0.16615 7.83099C0.219267 7.88454 0.282461 7.92705 0.352088 7.95606C0.421714 7.98507 0.496396 8 0.571824 8C0.647251 8 0.721933 7.98507 0.79156 7.95606C0.861186 7.92705 0.924381 7.88454 0.977497 7.83099L4.40572 4.40281C4.51128 4.29639 4.57079 4.15275 4.57142 4.00286Z\" fill=\"#BBBDC5\"/>\r\n </svg>\r\n } @else if (isSelected(item)) {\r\n <svg width=\"10\" height=\"7\" viewBox=\"0 0 10 7\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M3.72939 6.28273C3.64166 6.28324 3.55468 6.26642 3.47346 6.23324C3.39223 6.20007 3.31835 6.15118 3.25606 6.08939L0.196061 3.00273C0.0705253 2.87719 -1.32274e-09 2.70693 0 2.52939C1.32273e-09 2.35186 0.0705253 2.1816 0.196061 2.05606C0.321597 1.93053 0.49186 1.86 0.669394 1.86C0.846929 1.86 1.01719 1.93053 1.14273 2.05606L3.72939 4.64939L8.17606 0.196061C8.3016 0.0705253 8.47186 -3.49963e-09 8.64939 0C8.82693 3.49963e-09 8.99719 0.0705253 9.12273 0.196061C9.24826 0.321597 9.31879 0.49186 9.31879 0.669395C9.31879 0.846929 9.24826 1.01719 9.12273 1.14273L4.20273 6.06273C4.07921 6.19434 3.90963 6.27316 3.72939 6.28273V6.28273Z\" fill=\"#141414\"/>\r\n </svg>\r\n }\r\n </div>\r\n }\r\n @if (filteredItems().length === 0) {\r\n <div class=\"hierarchical-option-empty\">No records found</div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".hierarchical-select-container{@apply relative w-full box-border;}.hierarchical-select-field{@apply relative w-full;}.hierarchical-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded transition-all duration-200 px-3 py-2.5 cursor-pointer;}.hierarchical-select-control.focused{@apply border-[#6B7080] shadow-none z-10;}.hierarchical-select-control.disabled{@apply bg-[#F4F4F6] cursor-not-allowed opacity-60;}.hierarchical-select-control.disabled .hierarchical-placeholder{@apply text-gray-400;}.hierarchical-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full min-w-0;}.hierarchical-placeholder{@apply text-[#6B7080] font-normal text-sm truncate w-full pointer-events-none;}.hierarchical-value-label{@apply font-normal text-sm leading-[18px] text-[#141414] truncate w-full flex items-center;}.hierarchical-actions{@apply flex items-center gap-2 flex-shrink-0;}.hierarchical-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.hierarchical-arrow{@apply flex-shrink-0 text-gray-400 transition-transform duration-200;}.hierarchical-arrow.open{@apply rotate-180;}.hierarchical-dropdown-panel{@apply absolute left-0 w-full min-w-[250px] max-w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[99] overflow-hidden cursor-default p-2.5;}.hierarchical-dropdown-panel[data-position=bottom]{top:calc(100% + 4px);bottom:auto}.hierarchical-dropdown-panel[data-position=top]{bottom:calc(100% + 4px);top:auto}.hierarchical-dropdown-panel-fixed{z-index:10050}.hierarchical-search{@apply px-2 pt-2;}.hierarchical-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.hierarchical-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.hierarchical-search-input:-moz-focusring{outline:none}.hierarchical-back{@apply w-full text-left px-2.5 py-2 text-sm text-[#141414] bg-[#F8F8F8] rounded-md transition-colors mt-1 flex items-center gap-1.5;}.hierarchical-options-list{@apply overflow-auto relative flex flex-col gap-0.5 mt-1;}@media (max-height: 700px){.hierarchical-options-list{max-height:124px}}@media (min-height: 701px) and (max-height: 900px){.hierarchical-options-list{max-height:164px}}@media (min-height: 901px){.hierarchical-options-list{max-height:204px}}.hierarchical-option{@apply flex items-center justify-between gap-2 p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414] rounded-md;}.hierarchical-option.disabled-item{@apply opacity-50 cursor-not-allowed;}.hierarchical-option.disabled-item:hover{@apply bg-transparent;}.hierarchical-option:hover,.hierarchical-option.selected{@apply bg-[#F8F8F8];}.hierarchical-option.selected.disabled-item{@apply bg-transparent;}.hierarchical-option-label{@apply flex-1 truncate;}.hierarchical-option-chevron{@apply flex-shrink-0 text-[#6B7080];}.hierarchical-option-check{@apply flex-shrink-0 text-[#141414];}.hierarchical-option-empty{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}.input-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] mb-1.5 inline-block;}.input-label-required{@apply text-[#E7000B];}.hierarchical-options-list::-webkit-scrollbar{width:6px}.hierarchical-options-list::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.hierarchical-options-list::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.hierarchical-options-list::-webkit-scrollbar-thumb:hover{background:#909090}.hierarchical-breadcrumb-node{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.breadcrumb-separator{margin:0 6px;flex-shrink:0}.hierarchical-select-control.hierarchical-select-control-has-error{@apply border-[#d11e14];}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition", "bkTooltipScrollable", "bkTooltipMaxHeight", "bkTooltipSize", "bkTooltipAutoHeight"] }] });
|
|
8841
|
+
], viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }, { propertyName: "controlWrapper", first: true, predicate: ["controlWrapper"], descendants: true }, { propertyName: "dropdownPanel", first: true, predicate: ["dropdownPanel"], descendants: true }], ngImport: i0, template: "<div class=\"hierarchical-select-container\">\r\n @if (label()) {\r\n <label\r\n class=\"input-label\"\r\n (click)=\"openFromLabel($event)\">\r\n {{ label() }}\r\n @if (required()) {\r\n <span class=\"input-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"hierarchical-select-field\">\r\n <div\r\n #controlWrapper\r\n class=\"hierarchical-select-control\"\r\n [ngClass]=\"{ 'hierarchical-select-control-has-error': hasError() }\"\r\n tabindex=\"0\"\r\n [class.focused]=\"isOpen()\"\r\n [class.disabled]=\"isDisabled()\"\r\n (mousedown)=\"toggleDropdown($event)\">\r\n @if (iconSrc()) {\r\n <img [src]=\"iconSrc()\" [alt]=\"iconAlt()\" class=\"shrink-0\" />\r\n }\r\n <div class=\"hierarchical-value-container\">\r\n @if (!selected()) {\r\n <div class=\"hierarchical-placeholder\">{{ placeholder() }}</div>\r\n } @else {\r\n <div class=\"hierarchical-value-label\" [style.color]=\"resolveColor(selected())\">\r\n @for (node of displayPath(); track getValue(node); let last = $last) {\r\n <span\r\n #breadNode\r\n class=\"hierarchical-breadcrumb-node\"\r\n [bkTooltip]=\"breadNode.scrollWidth > breadNode.clientWidth ? getLabel(node) : ''\"\r\n bkTooltipPosition=\"top\">{{ getLabel(node) }}</span>\r\n\r\n @if (!last) {\r\n <svg\r\n class=\"breadcrumb-separator\"\r\n width=\"5\"\r\n height=\"8\"\r\n viewBox=\"0 0 5 8\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M4.57142 4.00286C4.57185 3.92766 4.55744 3.85312 4.52901 3.78351C4.50057 3.71389 4.45868 3.65058 4.40572 3.59719L0.977497 0.169008C0.924381 0.115455 0.861186 0.0729493 0.79156 0.0439419C0.721933 0.0149346 0.647251 0 0.571824 0C0.496396 0 0.421714 0.0149346 0.352088 0.0439419C0.282461 0.0729493 0.219267 0.115455 0.16615 0.169008C0.059732 0.27606 0 0.420874 0 0.57182C0 0.722766 0.059732 0.867579 0.16615 0.974631L3.19442 4.00286L0.16615 7.02537C0.059732 7.13242 0 7.27723 0 7.42818C0 7.57913 0.059732 7.72394 0.16615 7.83099C0.219267 7.88454 0.282461 7.92705 0.352088 7.95606C0.421714 7.98507 0.496396 8 0.571824 8C0.647251 8 0.721933 7.98507 0.79156 7.95606C0.861186 7.92705 0.924381 7.88454 0.977497 7.83099L4.40572 4.40281C4.51128 4.29639 4.57079 4.15275 4.57142 4.00286Z\"\r\n fill=\"#BBBDC5\"/>\r\n </svg>\r\n }\r\n }\r\n </div>\r\n\r\n }\r\n </div>\r\n <div class=\"hierarchical-actions\">\r\n @if (clearable() && selected() && !isDisabled()) {\r\n <span class=\"hierarchical-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\" [bkTooltip]=\"clearTooltip()\" bkTooltipPosition=\"top\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n </span>\r\n }\r\n <span class=\"hierarchical-arrow\" [class.open]=\"isOpen()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"m6 9 6 6 6-6\"/>\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n class=\"hierarchical-dropdown-panel\"\r\n [attr.data-position]=\"placement()\"\r\n [class.hierarchical-dropdown-panel-fixed]=\"appendToBody()\"\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"appendToBody() ? getTop() : null\"\r\n [style.bottom]=\"appendToBody() ? getBottom() : null\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\">\r\n @if (searchable()) {\r\n <div class=\"hierarchical-search\">\r\n <div class=\"hierarchical-search-wrapper\">\r\n <svg class=\"text-[#BBBDC5] mr-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\">\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input\r\n #searchInput\r\n type=\"text\"\r\n class=\"hierarchical-search-input\"\r\n [value]=\"searchTerm()\"\r\n [placeholder]=\"searchPlaceholder()\"\r\n (input)=\"onSearchInput($event)\"\r\n (click)=\"$event.stopPropagation()\" />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (showBack()) {\r\n <button\r\n type=\"button\"\r\n class=\"hierarchical-back\"\r\n (click)=\"goBack(); $event.stopPropagation()\">\r\n <span>\r\n <svg width=\"6\" height=\"10\" viewBox=\"0 0 6 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n<path d=\"M4.59961 0.599976L0.599609 4.59998L4.59961 8.59998\" stroke=\"#141414\" stroke-width=\"1.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n</svg>\r\n\r\n </span>\r\n {{ backToMainText() }}\r\n </button>\r\n }\r\n\r\n <div class=\"hierarchical-options-list\">\r\n @for (item of filteredItems(); track getValue(item)) {\r\n <div\r\n class=\"hierarchical-option\"\r\n [class.selected]=\"isSelected(item)\"\r\n [class.disabled-item]=\"item.disabled\"\r\n [class.cursor-not-allowed]=\"item.disabled\"\r\n (mousedown)=\"selectItem(item, $event)\">\r\n <span\r\n #optLabel\r\n class=\"hierarchical-option-label\"\r\n [style.color]=\"resolveColor(item)\"\r\n [bkTooltip]=\"optLabel.scrollWidth > optLabel.clientWidth ? getLabel(item) : ''\"\r\n bkTooltipPosition=\"top\">{{ getLabel(item) }}</span>\r\n @if (hasChildren(item)) {\r\n <svg width=\"5\" height=\"8\" viewBox=\"0 0 5 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M4.57142 4.00286C4.57185 3.92766 4.55744 3.85312 4.52901 3.78351C4.50057 3.71389 4.45868 3.65058 4.40572 3.59719L0.977497 0.169008C0.924381 0.115455 0.861186 0.0729493 0.79156 0.0439419C0.721933 0.0149346 0.647251 0 0.571824 0C0.496396 0 0.421714 0.0149346 0.352088 0.0439419C0.282461 0.0729493 0.219267 0.115455 0.16615 0.169008C0.059732 0.27606 0 0.420874 0 0.57182C0 0.722766 0.059732 0.867579 0.16615 0.974631L3.19442 4.00286L0.16615 7.02537C0.059732 7.13242 0 7.27723 0 7.42818C0 7.57913 0.059732 7.72394 0.16615 7.83099C0.219267 7.88454 0.282461 7.92705 0.352088 7.95606C0.421714 7.98507 0.496396 8 0.571824 8C0.647251 8 0.721933 7.98507 0.79156 7.95606C0.861186 7.92705 0.924381 7.88454 0.977497 7.83099L4.40572 4.40281C4.51128 4.29639 4.57079 4.15275 4.57142 4.00286Z\" fill=\"#BBBDC5\"/>\r\n </svg>\r\n } @else if (isSelected(item)) {\r\n <svg width=\"10\" height=\"7\" viewBox=\"0 0 10 7\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M3.72939 6.28273C3.64166 6.28324 3.55468 6.26642 3.47346 6.23324C3.39223 6.20007 3.31835 6.15118 3.25606 6.08939L0.196061 3.00273C0.0705253 2.87719 -1.32274e-09 2.70693 0 2.52939C1.32273e-09 2.35186 0.0705253 2.1816 0.196061 2.05606C0.321597 1.93053 0.49186 1.86 0.669394 1.86C0.846929 1.86 1.01719 1.93053 1.14273 2.05606L3.72939 4.64939L8.17606 0.196061C8.3016 0.0705253 8.47186 -3.49963e-09 8.64939 0C8.82693 3.49963e-09 8.99719 0.0705253 9.12273 0.196061C9.24826 0.321597 9.31879 0.49186 9.31879 0.669395C9.31879 0.846929 9.24826 1.01719 9.12273 1.14273L4.20273 6.06273C4.07921 6.19434 3.90963 6.27316 3.72939 6.28273V6.28273Z\" fill=\"#141414\"/>\r\n </svg>\r\n }\r\n </div>\r\n }\r\n @if (filteredItems().length === 0) {\r\n <div class=\"hierarchical-option-empty\">No records found</div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".hierarchical-select-container{@apply relative w-full box-border;}.hierarchical-select-field{@apply relative w-full;}.hierarchical-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded transition-all duration-200 px-3 py-2.5 cursor-pointer;}.hierarchical-select-control.focused{@apply border-[#6B7080] shadow-none z-10;}.hierarchical-select-control.disabled{@apply cursor-not-allowed opacity-60;background-color:#f4f4f6!important;border-color:#e3e3e7!important;color:#a1a3ae!important}.hierarchical-select-control.disabled .hierarchical-placeholder{@apply text-gray-400;}.hierarchical-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full min-w-0;}.hierarchical-placeholder{@apply text-[#6B7080] font-normal text-sm truncate w-full pointer-events-none;}.hierarchical-value-row{@apply flex items-center gap-1.5 w-full min-w-0;}.hierarchical-value-label{@apply font-normal text-sm leading-[18px] text-[#141414] truncate w-full flex items-center;}.hierarchical-dot{@apply inline-block w-2 h-2 rounded-full shrink-0;}.hierarchical-option-body{@apply flex items-center gap-2 min-w-0 flex-1;}.hierarchical-actions{@apply flex items-center gap-2 flex-shrink-0;}.hierarchical-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.hierarchical-arrow{@apply flex-shrink-0 text-gray-400 transition-transform duration-200;}.hierarchical-arrow.open{@apply rotate-180;}.hierarchical-dropdown-panel{@apply absolute left-0 w-full min-w-[250px] max-w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[99] overflow-hidden cursor-default p-2.5;}.hierarchical-dropdown-panel[data-position=bottom]{top:calc(100% + 4px);bottom:auto}.hierarchical-dropdown-panel[data-position=top]{bottom:calc(100% + 4px);top:auto}.hierarchical-dropdown-panel-fixed{z-index:10050}.hierarchical-search{@apply px-2 pt-2;}.hierarchical-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.hierarchical-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.hierarchical-back{@apply w-full text-left px-2.5 py-2 text-sm text-[#141414] bg-[#F8F8F8] rounded-md transition-colors mt-1 flex items-center gap-1.5;}.hierarchical-options-list{@apply overflow-auto relative flex flex-col gap-0.5 mt-1;}@media (max-height: 700px){.hierarchical-options-list{max-height:124px}}@media (min-height: 701px) and (max-height: 900px){.hierarchical-options-list{max-height:164px}}@media (min-height: 901px){.hierarchical-options-list{max-height:204px}}.hierarchical-option{@apply flex items-center justify-between gap-2 p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414] rounded-md;}.hierarchical-option.disabled-item{@apply opacity-50 cursor-not-allowed;}.hierarchical-option.disabled-item:hover{@apply bg-transparent;}.hierarchical-option:hover{@apply bg-[#f9f9f9];}.hierarchical-option.selected{@apply bg-[#f7f7f7];}.hierarchical-option.selected.disabled-item{@apply bg-transparent;}.hierarchical-option-label{@apply flex-1 truncate;}.hierarchical-option-chevron{@apply flex-shrink-0 text-[#6B7080];}.hierarchical-option-check{@apply flex-shrink-0 text-[#141414];}.hierarchical-option-empty{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}.input-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] mb-1.5 inline-block;}.input-label-required{@apply text-[#E7000B];}.hierarchical-options-list::-webkit-scrollbar{width:6px}.hierarchical-options-list::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.hierarchical-options-list::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.hierarchical-options-list::-webkit-scrollbar-thumb:hover{background:#909090}.hierarchical-breadcrumb-node{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.breadcrumb-separator{margin:0 6px;flex-shrink:0}.hierarchical-select-control.hierarchical-select-control-has-error{border-color:#d11e14!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition", "bkTooltipScrollable", "bkTooltipMaxHeight", "bkTooltipSize", "bkTooltipAutoHeight"] }] });
|
|
8391
8842
|
}
|
|
8392
8843
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkHierarchicalSelect, decorators: [{
|
|
8393
8844
|
type: Component,
|
|
@@ -8397,8 +8848,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
8397
8848
|
useExisting: forwardRef(() => BkHierarchicalSelect),
|
|
8398
8849
|
multi: true,
|
|
8399
8850
|
},
|
|
8400
|
-
], template: "<div class=\"hierarchical-select-container\">\r\n @if (label()) {\r\n <label\r\n class=\"input-label\"\r\n (click)=\"openFromLabel($event)\">\r\n {{ label() }}\r\n @if (required()) {\r\n <span class=\"input-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"hierarchical-select-field\">\r\n <div\r\n #controlWrapper\r\n class=\"hierarchical-select-control\"\r\n [ngClass]=\"{ 'hierarchical-select-control-has-error': hasError() }\"\r\n tabindex=\"0\"\r\n [class.focused]=\"isOpen()\"\r\n [class.disabled]=\"isDisabled()\"\r\n (mousedown)=\"toggleDropdown($event)\">\r\n @if (iconSrc()) {\r\n <img [src]=\"iconSrc()\" [alt]=\"iconAlt()\" class=\"shrink-0\" />\r\n }\r\n <div class=\"hierarchical-value-container\">\r\n @if (!selected()) {\r\n <div class=\"hierarchical-placeholder\">{{ placeholder() }}</div>\r\n } @else {\r\n <div class=\"hierarchical-value-label\" [style.color]=\"resolveColor(selected())\">\r\n @for (node of displayPath(); track getValue(node); let last = $last) {\r\n <span\r\n #breadNode\r\n class=\"hierarchical-breadcrumb-node\"\r\n [bkTooltip]=\"breadNode.scrollWidth > breadNode.clientWidth ? getLabel(node) : ''\"\r\n bkTooltipPosition=\"top\">{{ getLabel(node) }}</span>\r\n\r\n @if (!last) {\r\n <svg\r\n class=\"breadcrumb-separator\"\r\n width=\"5\"\r\n height=\"8\"\r\n viewBox=\"0 0 5 8\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M4.57142 4.00286C4.57185 3.92766 4.55744 3.85312 4.52901 3.78351C4.50057 3.71389 4.45868 3.65058 4.40572 3.59719L0.977497 0.169008C0.924381 0.115455 0.861186 0.0729493 0.79156 0.0439419C0.721933 0.0149346 0.647251 0 0.571824 0C0.496396 0 0.421714 0.0149346 0.352088 0.0439419C0.282461 0.0729493 0.219267 0.115455 0.16615 0.169008C0.059732 0.27606 0 0.420874 0 0.57182C0 0.722766 0.059732 0.867579 0.16615 0.974631L3.19442 4.00286L0.16615 7.02537C0.059732 7.13242 0 7.27723 0 7.42818C0 7.57913 0.059732 7.72394 0.16615 7.83099C0.219267 7.88454 0.282461 7.92705 0.352088 7.95606C0.421714 7.98507 0.496396 8 0.571824 8C0.647251 8 0.721933 7.98507 0.79156 7.95606C0.861186 7.92705 0.924381 7.88454 0.977497 7.83099L4.40572 4.40281C4.51128 4.29639 4.57079 4.15275 4.57142 4.00286Z\"\r\n fill=\"#BBBDC5\"/>\r\n </svg>\r\n }\r\n }\r\n </div>\r\n\r\n }\r\n </div>\r\n <div class=\"hierarchical-actions\">\r\n @if (clearable() && selected() && !isDisabled()) {\r\n <span class=\"hierarchical-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\" [bkTooltip]=\"clearTooltip()\" bkTooltipPosition=\"top\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n </span>\r\n }\r\n <span class=\"hierarchical-arrow\" [class.open]=\"isOpen()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"m6 9 6 6 6-6\"/>\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n class=\"hierarchical-dropdown-panel\"\r\n [attr.data-position]=\"placement()\"\r\n [class.hierarchical-dropdown-panel-fixed]=\"appendToBody()\"\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"appendToBody() ? getTop() : null\"\r\n [style.bottom]=\"appendToBody() ? getBottom() : null\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\">\r\n @if (searchable()) {\r\n <div class=\"hierarchical-search\">\r\n <div class=\"hierarchical-search-wrapper\">\r\n <svg class=\"text-[#BBBDC5] mr-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\">\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input\r\n #searchInput\r\n type=\"text\"\r\n class=\"hierarchical-search-input\"\r\n [value]=\"searchTerm()\"\r\n [placeholder]=\"searchPlaceholder()\"\r\n (input)=\"onSearchInput($event)\"\r\n (click)=\"$event.stopPropagation()\" />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (showBack()) {\r\n <button\r\n type=\"button\"\r\n class=\"hierarchical-back\"\r\n (click)=\"goBack(); $event.stopPropagation()\">\r\n <span>\r\n <svg width=\"6\" height=\"10\" viewBox=\"0 0 6 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n<path d=\"M4.59961 0.599976L0.599609 4.59998L4.59961 8.59998\" stroke=\"#141414\" stroke-width=\"1.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n</svg>\r\n\r\n </span>\r\n {{ backToMainText() }}\r\n </button>\r\n }\r\n\r\n <div class=\"hierarchical-options-list\">\r\n @for (item of filteredItems(); track getValue(item)) {\r\n <div\r\n class=\"hierarchical-option\"\r\n [class.selected]=\"isSelected(item)\"\r\n [class.disabled-item]=\"item.disabled\"\r\n [class.cursor-not-allowed]=\"item.disabled\"\r\n (mousedown)=\"selectItem(item, $event)\">\r\n <span\r\n #optLabel\r\n class=\"hierarchical-option-label\"\r\n [style.color]=\"resolveColor(item)\"\r\n [bkTooltip]=\"optLabel.scrollWidth > optLabel.clientWidth ? getLabel(item) : ''\"\r\n bkTooltipPosition=\"top\">{{ getLabel(item) }}</span>\r\n @if (hasChildren(item)) {\r\n <svg width=\"5\" height=\"8\" viewBox=\"0 0 5 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M4.57142 4.00286C4.57185 3.92766 4.55744 3.85312 4.52901 3.78351C4.50057 3.71389 4.45868 3.65058 4.40572 3.59719L0.977497 0.169008C0.924381 0.115455 0.861186 0.0729493 0.79156 0.0439419C0.721933 0.0149346 0.647251 0 0.571824 0C0.496396 0 0.421714 0.0149346 0.352088 0.0439419C0.282461 0.0729493 0.219267 0.115455 0.16615 0.169008C0.059732 0.27606 0 0.420874 0 0.57182C0 0.722766 0.059732 0.867579 0.16615 0.974631L3.19442 4.00286L0.16615 7.02537C0.059732 7.13242 0 7.27723 0 7.42818C0 7.57913 0.059732 7.72394 0.16615 7.83099C0.219267 7.88454 0.282461 7.92705 0.352088 7.95606C0.421714 7.98507 0.496396 8 0.571824 8C0.647251 8 0.721933 7.98507 0.79156 7.95606C0.861186 7.92705 0.924381 7.88454 0.977497 7.83099L4.40572 4.40281C4.51128 4.29639 4.57079 4.15275 4.57142 4.00286Z\" fill=\"#BBBDC5\"/>\r\n </svg>\r\n } @else if (isSelected(item)) {\r\n <svg width=\"10\" height=\"7\" viewBox=\"0 0 10 7\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M3.72939 6.28273C3.64166 6.28324 3.55468 6.26642 3.47346 6.23324C3.39223 6.20007 3.31835 6.15118 3.25606 6.08939L0.196061 3.00273C0.0705253 2.87719 -1.32274e-09 2.70693 0 2.52939C1.32273e-09 2.35186 0.0705253 2.1816 0.196061 2.05606C0.321597 1.93053 0.49186 1.86 0.669394 1.86C0.846929 1.86 1.01719 1.93053 1.14273 2.05606L3.72939 4.64939L8.17606 0.196061C8.3016 0.0705253 8.47186 -3.49963e-09 8.64939 0C8.82693 3.49963e-09 8.99719 0.0705253 9.12273 0.196061C9.24826 0.321597 9.31879 0.49186 9.31879 0.669395C9.31879 0.846929 9.24826 1.01719 9.12273 1.14273L4.20273 6.06273C4.07921 6.19434 3.90963 6.27316 3.72939 6.28273V6.28273Z\" fill=\"#141414\"/>\r\n </svg>\r\n }\r\n </div>\r\n }\r\n @if (filteredItems().length === 0) {\r\n <div class=\"hierarchical-option-empty\">No records found</div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".hierarchical-select-container{@apply relative w-full box-border;}.hierarchical-select-field{@apply relative w-full;}.hierarchical-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded transition-all duration-200 px-3 py-2.5 cursor-pointer;}.hierarchical-select-control.focused{@apply border-[#6B7080] shadow-none z-10;}.hierarchical-select-control.disabled{@apply bg-[#F4F4F6] cursor-not-allowed opacity-60;}.hierarchical-select-control.disabled .hierarchical-placeholder{@apply text-gray-400;}.hierarchical-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full min-w-0;}.hierarchical-placeholder{@apply text-[#6B7080] font-normal text-sm truncate w-full pointer-events-none;}.hierarchical-value-label{@apply font-normal text-sm leading-[18px] text-[#141414] truncate w-full flex items-center;}.hierarchical-actions{@apply flex items-center gap-2 flex-shrink-0;}.hierarchical-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.hierarchical-arrow{@apply flex-shrink-0 text-gray-400 transition-transform duration-200;}.hierarchical-arrow.open{@apply rotate-180;}.hierarchical-dropdown-panel{@apply absolute left-0 w-full min-w-[250px] max-w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[99] overflow-hidden cursor-default p-2.5;}.hierarchical-dropdown-panel[data-position=bottom]{top:calc(100% + 4px);bottom:auto}.hierarchical-dropdown-panel[data-position=top]{bottom:calc(100% + 4px);top:auto}.hierarchical-dropdown-panel-fixed{z-index:10050}.hierarchical-search{@apply px-2 pt-2;}.hierarchical-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.hierarchical-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.hierarchical-search-input:-moz-focusring{outline:none}.hierarchical-back{@apply w-full text-left px-2.5 py-2 text-sm text-[#141414] bg-[#F8F8F8] rounded-md transition-colors mt-1 flex items-center gap-1.5;}.hierarchical-options-list{@apply overflow-auto relative flex flex-col gap-0.5 mt-1;}@media (max-height: 700px){.hierarchical-options-list{max-height:124px}}@media (min-height: 701px) and (max-height: 900px){.hierarchical-options-list{max-height:164px}}@media (min-height: 901px){.hierarchical-options-list{max-height:204px}}.hierarchical-option{@apply flex items-center justify-between gap-2 p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414] rounded-md;}.hierarchical-option.disabled-item{@apply opacity-50 cursor-not-allowed;}.hierarchical-option.disabled-item:hover{@apply bg-transparent;}.hierarchical-option:hover,.hierarchical-option.selected{@apply bg-[#F8F8F8];}.hierarchical-option.selected.disabled-item{@apply bg-transparent;}.hierarchical-option-label{@apply flex-1 truncate;}.hierarchical-option-chevron{@apply flex-shrink-0 text-[#6B7080];}.hierarchical-option-check{@apply flex-shrink-0 text-[#141414];}.hierarchical-option-empty{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}.input-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] mb-1.5 inline-block;}.input-label-required{@apply text-[#E7000B];}.hierarchical-options-list::-webkit-scrollbar{width:6px}.hierarchical-options-list::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.hierarchical-options-list::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.hierarchical-options-list::-webkit-scrollbar-thumb:hover{background:#909090}.hierarchical-breadcrumb-node{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.breadcrumb-separator{margin:0 6px;flex-shrink:0}.hierarchical-select-control.hierarchical-select-control-has-error{@apply border-[#d11e14];}\n"] }]
|
|
8401
|
-
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], labelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelKey", required: false }] }], valueKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueKey", required: false }] }], childrenKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "childrenKey", required: false }] }], clearTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearTooltip", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], iconSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconSrc", required: false }] }], iconAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconAlt", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], allowParentSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowParentSelection", required: false }] }], backToMainText: [{ type: i0.Input, args: [{ isSignal: true, alias: "backToMainText", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], appendToBody: [{ type: i0.Input, args: [{ isSignal: true, alias: "appendToBody", required: false }] }], dropdownPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropdownPosition", required: false }] }], colorKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorKey", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], restrictKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "restrictKey", required: false }] }], hasError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasError", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], clear: [{ type: i0.Output, args: ["clear"] }], searchInput: [{
|
|
8851
|
+
], template: "<div class=\"hierarchical-select-container\">\r\n @if (label()) {\r\n <label\r\n class=\"input-label\"\r\n (click)=\"openFromLabel($event)\">\r\n {{ label() }}\r\n @if (required()) {\r\n <span class=\"input-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"hierarchical-select-field\">\r\n <div\r\n #controlWrapper\r\n class=\"hierarchical-select-control\"\r\n [ngClass]=\"{ 'hierarchical-select-control-has-error': hasError() }\"\r\n tabindex=\"0\"\r\n [class.focused]=\"isOpen()\"\r\n [class.disabled]=\"isDisabled()\"\r\n (mousedown)=\"toggleDropdown($event)\">\r\n @if (iconSrc()) {\r\n <img [src]=\"iconSrc()\" [alt]=\"iconAlt()\" class=\"shrink-0\" />\r\n }\r\n <div class=\"hierarchical-value-container\">\r\n @if (!selected()) {\r\n <div class=\"hierarchical-placeholder\">{{ placeholder() }}</div>\r\n } @else {\r\n <div class=\"hierarchical-value-label\" [style.color]=\"resolveColor(selected())\">\r\n @for (node of displayPath(); track getValue(node); let last = $last) {\r\n <span\r\n #breadNode\r\n class=\"hierarchical-breadcrumb-node\"\r\n [bkTooltip]=\"breadNode.scrollWidth > breadNode.clientWidth ? getLabel(node) : ''\"\r\n bkTooltipPosition=\"top\">{{ getLabel(node) }}</span>\r\n\r\n @if (!last) {\r\n <svg\r\n class=\"breadcrumb-separator\"\r\n width=\"5\"\r\n height=\"8\"\r\n viewBox=\"0 0 5 8\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M4.57142 4.00286C4.57185 3.92766 4.55744 3.85312 4.52901 3.78351C4.50057 3.71389 4.45868 3.65058 4.40572 3.59719L0.977497 0.169008C0.924381 0.115455 0.861186 0.0729493 0.79156 0.0439419C0.721933 0.0149346 0.647251 0 0.571824 0C0.496396 0 0.421714 0.0149346 0.352088 0.0439419C0.282461 0.0729493 0.219267 0.115455 0.16615 0.169008C0.059732 0.27606 0 0.420874 0 0.57182C0 0.722766 0.059732 0.867579 0.16615 0.974631L3.19442 4.00286L0.16615 7.02537C0.059732 7.13242 0 7.27723 0 7.42818C0 7.57913 0.059732 7.72394 0.16615 7.83099C0.219267 7.88454 0.282461 7.92705 0.352088 7.95606C0.421714 7.98507 0.496396 8 0.571824 8C0.647251 8 0.721933 7.98507 0.79156 7.95606C0.861186 7.92705 0.924381 7.88454 0.977497 7.83099L4.40572 4.40281C4.51128 4.29639 4.57079 4.15275 4.57142 4.00286Z\"\r\n fill=\"#BBBDC5\"/>\r\n </svg>\r\n }\r\n }\r\n </div>\r\n\r\n }\r\n </div>\r\n <div class=\"hierarchical-actions\">\r\n @if (clearable() && selected() && !isDisabled()) {\r\n <span class=\"hierarchical-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\" [bkTooltip]=\"clearTooltip()\" bkTooltipPosition=\"top\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n </span>\r\n }\r\n <span class=\"hierarchical-arrow\" [class.open]=\"isOpen()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"m6 9 6 6 6-6\"/>\r\n </svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n class=\"hierarchical-dropdown-panel\"\r\n [attr.data-position]=\"placement()\"\r\n [class.hierarchical-dropdown-panel-fixed]=\"appendToBody()\"\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"appendToBody() ? getTop() : null\"\r\n [style.bottom]=\"appendToBody() ? getBottom() : null\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\">\r\n @if (searchable()) {\r\n <div class=\"hierarchical-search\">\r\n <div class=\"hierarchical-search-wrapper\">\r\n <svg class=\"text-[#BBBDC5] mr-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\">\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input\r\n #searchInput\r\n type=\"text\"\r\n class=\"hierarchical-search-input\"\r\n [value]=\"searchTerm()\"\r\n [placeholder]=\"searchPlaceholder()\"\r\n (input)=\"onSearchInput($event)\"\r\n (click)=\"$event.stopPropagation()\" />\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (showBack()) {\r\n <button\r\n type=\"button\"\r\n class=\"hierarchical-back\"\r\n (click)=\"goBack(); $event.stopPropagation()\">\r\n <span>\r\n <svg width=\"6\" height=\"10\" viewBox=\"0 0 6 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n<path d=\"M4.59961 0.599976L0.599609 4.59998L4.59961 8.59998\" stroke=\"#141414\" stroke-width=\"1.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n</svg>\r\n\r\n </span>\r\n {{ backToMainText() }}\r\n </button>\r\n }\r\n\r\n <div class=\"hierarchical-options-list\">\r\n @for (item of filteredItems(); track getValue(item)) {\r\n <div\r\n class=\"hierarchical-option\"\r\n [class.selected]=\"isSelected(item)\"\r\n [class.disabled-item]=\"item.disabled\"\r\n [class.cursor-not-allowed]=\"item.disabled\"\r\n (mousedown)=\"selectItem(item, $event)\">\r\n <span\r\n #optLabel\r\n class=\"hierarchical-option-label\"\r\n [style.color]=\"resolveColor(item)\"\r\n [bkTooltip]=\"optLabel.scrollWidth > optLabel.clientWidth ? getLabel(item) : ''\"\r\n bkTooltipPosition=\"top\">{{ getLabel(item) }}</span>\r\n @if (hasChildren(item)) {\r\n <svg width=\"5\" height=\"8\" viewBox=\"0 0 5 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M4.57142 4.00286C4.57185 3.92766 4.55744 3.85312 4.52901 3.78351C4.50057 3.71389 4.45868 3.65058 4.40572 3.59719L0.977497 0.169008C0.924381 0.115455 0.861186 0.0729493 0.79156 0.0439419C0.721933 0.0149346 0.647251 0 0.571824 0C0.496396 0 0.421714 0.0149346 0.352088 0.0439419C0.282461 0.0729493 0.219267 0.115455 0.16615 0.169008C0.059732 0.27606 0 0.420874 0 0.57182C0 0.722766 0.059732 0.867579 0.16615 0.974631L3.19442 4.00286L0.16615 7.02537C0.059732 7.13242 0 7.27723 0 7.42818C0 7.57913 0.059732 7.72394 0.16615 7.83099C0.219267 7.88454 0.282461 7.92705 0.352088 7.95606C0.421714 7.98507 0.496396 8 0.571824 8C0.647251 8 0.721933 7.98507 0.79156 7.95606C0.861186 7.92705 0.924381 7.88454 0.977497 7.83099L4.40572 4.40281C4.51128 4.29639 4.57079 4.15275 4.57142 4.00286Z\" fill=\"#BBBDC5\"/>\r\n </svg>\r\n } @else if (isSelected(item)) {\r\n <svg width=\"10\" height=\"7\" viewBox=\"0 0 10 7\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M3.72939 6.28273C3.64166 6.28324 3.55468 6.26642 3.47346 6.23324C3.39223 6.20007 3.31835 6.15118 3.25606 6.08939L0.196061 3.00273C0.0705253 2.87719 -1.32274e-09 2.70693 0 2.52939C1.32273e-09 2.35186 0.0705253 2.1816 0.196061 2.05606C0.321597 1.93053 0.49186 1.86 0.669394 1.86C0.846929 1.86 1.01719 1.93053 1.14273 2.05606L3.72939 4.64939L8.17606 0.196061C8.3016 0.0705253 8.47186 -3.49963e-09 8.64939 0C8.82693 3.49963e-09 8.99719 0.0705253 9.12273 0.196061C9.24826 0.321597 9.31879 0.49186 9.31879 0.669395C9.31879 0.846929 9.24826 1.01719 9.12273 1.14273L4.20273 6.06273C4.07921 6.19434 3.90963 6.27316 3.72939 6.28273V6.28273Z\" fill=\"#141414\"/>\r\n </svg>\r\n }\r\n </div>\r\n }\r\n @if (filteredItems().length === 0) {\r\n <div class=\"hierarchical-option-empty\">No records found</div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".hierarchical-select-container{@apply relative w-full box-border;}.hierarchical-select-field{@apply relative w-full;}.hierarchical-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded transition-all duration-200 px-3 py-2.5 cursor-pointer;}.hierarchical-select-control.focused{@apply border-[#6B7080] shadow-none z-10;}.hierarchical-select-control.disabled{@apply cursor-not-allowed opacity-60;background-color:#f4f4f6!important;border-color:#e3e3e7!important;color:#a1a3ae!important}.hierarchical-select-control.disabled .hierarchical-placeholder{@apply text-gray-400;}.hierarchical-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full min-w-0;}.hierarchical-placeholder{@apply text-[#6B7080] font-normal text-sm truncate w-full pointer-events-none;}.hierarchical-value-row{@apply flex items-center gap-1.5 w-full min-w-0;}.hierarchical-value-label{@apply font-normal text-sm leading-[18px] text-[#141414] truncate w-full flex items-center;}.hierarchical-dot{@apply inline-block w-2 h-2 rounded-full shrink-0;}.hierarchical-option-body{@apply flex items-center gap-2 min-w-0 flex-1;}.hierarchical-actions{@apply flex items-center gap-2 flex-shrink-0;}.hierarchical-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.hierarchical-arrow{@apply flex-shrink-0 text-gray-400 transition-transform duration-200;}.hierarchical-arrow.open{@apply rotate-180;}.hierarchical-dropdown-panel{@apply absolute left-0 w-full min-w-[250px] max-w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[99] overflow-hidden cursor-default p-2.5;}.hierarchical-dropdown-panel[data-position=bottom]{top:calc(100% + 4px);bottom:auto}.hierarchical-dropdown-panel[data-position=top]{bottom:calc(100% + 4px);top:auto}.hierarchical-dropdown-panel-fixed{z-index:10050}.hierarchical-search{@apply px-2 pt-2;}.hierarchical-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.hierarchical-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.hierarchical-back{@apply w-full text-left px-2.5 py-2 text-sm text-[#141414] bg-[#F8F8F8] rounded-md transition-colors mt-1 flex items-center gap-1.5;}.hierarchical-options-list{@apply overflow-auto relative flex flex-col gap-0.5 mt-1;}@media (max-height: 700px){.hierarchical-options-list{max-height:124px}}@media (min-height: 701px) and (max-height: 900px){.hierarchical-options-list{max-height:164px}}@media (min-height: 901px){.hierarchical-options-list{max-height:204px}}.hierarchical-option{@apply flex items-center justify-between gap-2 p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414] rounded-md;}.hierarchical-option.disabled-item{@apply opacity-50 cursor-not-allowed;}.hierarchical-option.disabled-item:hover{@apply bg-transparent;}.hierarchical-option:hover{@apply bg-[#f9f9f9];}.hierarchical-option.selected{@apply bg-[#f7f7f7];}.hierarchical-option.selected.disabled-item{@apply bg-transparent;}.hierarchical-option-label{@apply flex-1 truncate;}.hierarchical-option-chevron{@apply flex-shrink-0 text-[#6B7080];}.hierarchical-option-check{@apply flex-shrink-0 text-[#141414];}.hierarchical-option-empty{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}.input-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] mb-1.5 inline-block;}.input-label-required{@apply text-[#E7000B];}.hierarchical-options-list::-webkit-scrollbar{width:6px}.hierarchical-options-list::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.hierarchical-options-list::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.hierarchical-options-list::-webkit-scrollbar-thumb:hover{background:#909090}.hierarchical-breadcrumb-node{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.breadcrumb-separator{margin:0 6px;flex-shrink:0}.hierarchical-select-control.hierarchical-select-control-has-error{border-color:#d11e14!important}\n"] }]
|
|
8852
|
+
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], labelKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelKey", required: false }] }], valueKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueKey", required: false }] }], childrenKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "childrenKey", required: false }] }], clearTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearTooltip", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], iconSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconSrc", required: false }] }], iconAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconAlt", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], allowParentSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowParentSelection", required: false }] }], backToMainText: [{ type: i0.Input, args: [{ isSignal: true, alias: "backToMainText", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], appendToBody: [{ type: i0.Input, args: [{ isSignal: true, alias: "appendToBody", required: false }] }], dropdownPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropdownPosition", required: false }] }], colorKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorKey", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], showDots: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDots", required: false }] }], inheritColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "inheritColor", required: false }] }], restrictKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "restrictKey", required: false }] }], hasError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasError", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], clear: [{ type: i0.Output, args: ["clear"] }], searchInput: [{
|
|
8402
8853
|
type: ViewChild,
|
|
8403
8854
|
args: ['searchInput']
|
|
8404
8855
|
}], controlWrapper: [{
|
|
@@ -8544,189 +8995,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
8544
8995
|
args: [{ selector: 'bk-toastr', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "<!-- Toast Container \u2013 fixed overlay -->\r\n<div class=\"toast-container\" [attr.data-position]=\"position$ | async\">\r\n\r\n @for (toast of (toasts$ | async) ?? []; track toast.id) {\r\n <div\r\n class=\"toast-item\"\r\n [attr.data-severity]=\"toast.severity\"\r\n [class.toast-item-inline]=\"toast.inline\"\r\n [class.toast-enter]=\"!toast.leaving\"\r\n [class.toast-leave]=\"toast.leaving\">\r\n\r\n <!-- \u2500\u2500 Icon \u2500\u2500 -->\r\n @if (toast.icon) {\r\n <svg class=\"toast-icon shrink-0\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\r\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <g [attr.clip-path]=\"'url(#clip_' + toast.id + ')'\">\r\n <path\r\n d=\"M10.0001 13.3334V10M10.0001 6.66671H10.0084M18.3334 10C18.3334 5.39767 14.6025 1.66671 10.0001 1.66671C5.39771 1.66671 1.66675 5.39767 1.66675 10C1.66675 14.6024 5.39771 18.3334 10.0001 18.3334C14.6025 18.3334 18.3334 14.6024 18.3334 10Z\"\r\n stroke-width=\"1.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </g>\r\n <defs>\r\n <clipPath [attr.id]=\"'clip_' + toast.id\">\r\n <rect width=\"20\" height=\"20\" fill=\"white\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n }\r\n\r\n <!-- \u2500\u2500 Content \u2500\u2500 -->\r\n <div class=\"toast-content flex-1 min-w-0\">\r\n <p class=\"toast-summary\">{{ toast.summary }}</p>\r\n @if (toast.detail) {\r\n <p class=\"toast-detail\">{{ toast.detail }}</p>\r\n }\r\n </div>\r\n\r\n <!-- \u2500\u2500 Action button \u2500\u2500 -->\r\n @if (toast.actionLabel) {\r\n <button type=\"button\" class=\"toast-action\" (click)=\"onAction($event, toast)\">\r\n {{ toast.actionLabel }}\r\n </button>\r\n }\r\n\r\n <!-- \u2500\u2500 Close button \u2500\u2500 -->\r\n <button type=\"button\" class=\"toast-close\" (click)=\"onClose($event, toast.id)\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M10.625 0.625L0.625 10.625M0.625 0.625L10.625 10.625\"\r\n stroke-width=\"1.25\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n\r\n </div>\r\n }\r\n\r\n</div>\r\n", styles: [".toast-container{@apply fixed flex flex-col gap-3 max-w-[100vw-2rem];z-index:2147483647!important;pointer-events:none}.toast-container[data-position=top-right]{@apply top-4 right-4;}.toast-container[data-position=top-left]{@apply top-4 left-4;}.toast-container[data-position=top-center]{@apply top-4 left-1/2 -translate-x-1/2;}.toast-container[data-position=bottom-right]{@apply bottom-4 right-4;}.toast-container[data-position=bottom-left]{@apply bottom-4 left-4;}.toast-container[data-position=bottom-center]{@apply bottom-4 left-1/2 -translate-x-1/2;}.toast-item{@apply flex items-center justify-start gap-3 py-2 px-4 rounded-lg border;box-shadow:0 4px 12px #00000014,0 1px 3px #0000000f;pointer-events:auto}.toast-item[data-severity=info]{@apply bg-[#1434CB] border-[#E5F3FF];}.toast-item[data-severity=info] .toast-icon path{stroke:#fff}.toast-item[data-severity=info] .toast-summary{@apply text-white;}.toast-item[data-severity=info] .toast-detail{@apply text-gray-200 text-xs;}.toast-item[data-severity=info] .toast-action{@apply bg-white text-[#1434CB] border border-[#1434CB];}.toast-item[data-severity=info] .toast-close path{stroke:#fff}.toast-item[data-severity=default]{@apply bg-gray-500 border-gray-50;}.toast-item[data-severity=default] .toast-icon path{stroke:#fff}.toast-item[data-severity=default] .toast-summary{@apply text-white;}.toast-item[data-severity=default] .toast-action{@apply bg-white text-gray-500;}.toast-item[data-severity=default] .toast-close path{stroke:#fff}.toast-item[data-severity=error]{@apply bg-[#C84144] border-[#FFF1F1];}.toast-item[data-severity=error] .toast-icon path{stroke:#fff}.toast-item[data-severity=error] .toast-summary{@apply text-white;}.toast-item[data-severity=error] .toast-detail{@apply text-gray-200 text-xs;}.toast-item[data-severity=error] .toast-action{@apply bg-white text-[#CB1432];}.toast-item[data-severity=error] .toast-close path{stroke:#fff}.toast-item[data-severity=warn]{@apply bg-[#CC6401] border-[#FFEED7];}.toast-item[data-severity=warn] .toast-icon path{stroke:#fff}.toast-item[data-severity=warn] .toast-summary{@apply text-white;}.toast-item[data-severity=warn] .toast-action{@apply bg-white text-[#CC6401];}.toast-item[data-severity=warn] .toast-close path{stroke:#fff}.toast-item[data-severity=success]{@apply bg-[#1E7735] border-[#F1FCF3];}.toast-item[data-severity=success] .toast-icon path{stroke:#fff}.toast-item[data-severity=success] .toast-summary{@apply text-white;}.toast-item[data-severity=success] .toast-action{@apply bg-white text-[#22973F];}.toast-item[data-severity=success] .toast-action:hover{@apply bg-[#22973F];}.toast-item[data-severity=success] .toast-close path{stroke:#fff}.toast-summary{@apply text-sm font-medium;}.toast-action{@apply shrink-0 py-1 px-2 text-xs font-medium leading-[18px] rounded-lg cursor-pointer border-none transition-colors;pointer-events:auto}.toast-close{@apply shrink-0 p-1 rounded cursor-pointer border-none bg-transparent transition-opacity;pointer-events:auto;position:relative;z-index:1}.toast-close:hover{@apply opacity-60;}.toast-close svg{display:block;pointer-events:none}.toast-close *{cursor:pointer}@media (max-width: 425px){.toast-container{width:calc(100vw - 2rem);max-width:100%}.toast-container[data-position=top-center],.toast-container[data-position=bottom-center]{left:50%!important;right:auto!important;transform:translate(-50%)!important;align-items:center}.toast-item:not(.toast-item-inline){display:grid;grid-template-areas:\"icon action close\" \"content content content\";grid-template-columns:auto 1fr auto;align-items:center;row-gap:6px}.toast-icon{grid-area:icon}.toast-content{grid-area:content}.toast-action{grid-area:action;justify-self:end}.toast-close{grid-area:close}}.toast-enter{animation:toastIn .3s ease-out forwards}.toast-leave{animation:toastOut .3s ease-in forwards}@keyframes toastIn{0%{opacity:0;transform:translateY(-10px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes toastOut{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(-10px) scale(.96)}}\n"] }]
|
|
8545
8996
|
}] });
|
|
8546
8997
|
|
|
8547
|
-
class BkAvatar {
|
|
8548
|
-
cdr;
|
|
8549
|
-
constructor(cdr) {
|
|
8550
|
-
this.cdr = cdr;
|
|
8551
|
-
}
|
|
8552
|
-
// ---------- Display Inputs ----------
|
|
8553
|
-
src = null;
|
|
8554
|
-
alt = 'Avatar';
|
|
8555
|
-
name = '';
|
|
8556
|
-
initialsOverride = '';
|
|
8557
|
-
tooltipContent = null;
|
|
8558
|
-
bgColor = null;
|
|
8559
|
-
textColor = null;
|
|
8560
|
-
size = 'md';
|
|
8561
|
-
variant = 'gray';
|
|
8562
|
-
fallback = 'auto';
|
|
8563
|
-
dot = 'none';
|
|
8564
|
-
dotPosition = 'bottom-right';
|
|
8565
|
-
// ---------- Outputs ----------
|
|
8566
|
-
/** Emits when the provided image URL fails to load */
|
|
8567
|
-
imageLoadError = new EventEmitter();
|
|
8568
|
-
// ---------- Internal State ----------
|
|
8569
|
-
initials = '';
|
|
8570
|
-
imageLoadFailed = false;
|
|
8571
|
-
// ---------- CVA Callbacks ----------
|
|
8572
|
-
onChange = (_value) => { };
|
|
8573
|
-
onTouched = () => { };
|
|
8574
|
-
/**
|
|
8575
|
-
* Called by the forms system when the model value changes (ngModel / formControl).
|
|
8576
|
-
* Sets the src directly and tells OnPush to re-check the template.
|
|
8577
|
-
*/
|
|
8578
|
-
writeValue(value) {
|
|
8579
|
-
this.src = value || null;
|
|
8580
|
-
this.imageLoadFailed = false;
|
|
8581
|
-
// OnPush won't detect this change on its own because writeValue
|
|
8582
|
-
// is called programmatically by the forms system — not through an
|
|
8583
|
-
// @Input binding. markForCheck tells Angular: "this component's
|
|
8584
|
-
// template might have changed, check it on the next CD cycle."
|
|
8585
|
-
this.cdr.markForCheck();
|
|
8586
|
-
}
|
|
8587
|
-
registerOnChange(fn) {
|
|
8588
|
-
this.onChange = fn;
|
|
8589
|
-
}
|
|
8590
|
-
registerOnTouched(fn) {
|
|
8591
|
-
this.onTouched = fn;
|
|
8592
|
-
}
|
|
8593
|
-
setDisabledState(_isDisabled) {
|
|
8594
|
-
// Display-only component — disabled doesn't change visual behaviour,
|
|
8595
|
-
// but we still honour the CVA contract.
|
|
8596
|
-
this.cdr.markForCheck();
|
|
8597
|
-
}
|
|
8598
|
-
// ---------- Lifecycle ----------
|
|
8599
|
-
ngOnChanges(changes) {
|
|
8600
|
-
if (changes['name'] || changes['initialsOverride']) {
|
|
8601
|
-
this.initials = this.initialsOverride || this.getInitials(this.name);
|
|
8602
|
-
}
|
|
8603
|
-
// Reset error state whenever a new src arrives via @Input
|
|
8604
|
-
if (changes['src']) {
|
|
8605
|
-
this.imageLoadFailed = false;
|
|
8606
|
-
}
|
|
8607
|
-
}
|
|
8608
|
-
onImageError() {
|
|
8609
|
-
this.imageLoadFailed = true;
|
|
8610
|
-
this.imageLoadError.emit();
|
|
8611
|
-
}
|
|
8612
|
-
// ---------- Derived UI ----------
|
|
8613
|
-
get showImage() {
|
|
8614
|
-
return !!(this.src) && !this.imageLoadFailed;
|
|
8615
|
-
}
|
|
8616
|
-
get showInitials() {
|
|
8617
|
-
if (this.showImage)
|
|
8618
|
-
return false;
|
|
8619
|
-
if (!this.name)
|
|
8620
|
-
return false;
|
|
8621
|
-
if (this.fallback === 'icon')
|
|
8622
|
-
return false;
|
|
8623
|
-
return true; // 'auto' and 'initials' both show initials when name is present
|
|
8624
|
-
}
|
|
8625
|
-
get showIcon() {
|
|
8626
|
-
return !this.showImage && !this.showInitials;
|
|
8627
|
-
}
|
|
8628
|
-
get containerClasses() {
|
|
8629
|
-
return [
|
|
8630
|
-
'avatar',
|
|
8631
|
-
this.size,
|
|
8632
|
-
VARIANT_MAP[this.variant]
|
|
8633
|
-
].join(' ');
|
|
8634
|
-
}
|
|
8635
|
-
get containerStyles() {
|
|
8636
|
-
const styles = {};
|
|
8637
|
-
if (this.bgColor) {
|
|
8638
|
-
styles['background'] = this.bgColor;
|
|
8639
|
-
}
|
|
8640
|
-
if (this.textColor) {
|
|
8641
|
-
styles['color'] = this.textColor;
|
|
8642
|
-
}
|
|
8643
|
-
return Object.keys(styles).length ? styles : null;
|
|
8644
|
-
}
|
|
8645
|
-
get resolvedTooltip() {
|
|
8646
|
-
return this.tooltipContent ?? this.name;
|
|
8647
|
-
}
|
|
8648
|
-
get dotClasses() {
|
|
8649
|
-
return [
|
|
8650
|
-
'avatar-dot',
|
|
8651
|
-
this.size,
|
|
8652
|
-
DOT_COLOR_MAP[this.dot],
|
|
8653
|
-
DOT_POSITION_MAP[this.dotPosition]
|
|
8654
|
-
].join(' ');
|
|
8655
|
-
}
|
|
8656
|
-
// ---------- Utils ----------
|
|
8657
|
-
getInitials(name) {
|
|
8658
|
-
if (!name?.trim())
|
|
8659
|
-
return '';
|
|
8660
|
-
const normalized = name.includes(',')
|
|
8661
|
-
? name.split(',').map(part => part.trim()).filter(Boolean).reverse().join(' ')
|
|
8662
|
-
: name.trim();
|
|
8663
|
-
const parts = normalized.split(/\s+/);
|
|
8664
|
-
if (parts.length === 1) {
|
|
8665
|
-
return parts[0].slice(0, 2).toUpperCase();
|
|
8666
|
-
}
|
|
8667
|
-
return (parts[0][0] + parts.at(-1)[0]).toUpperCase();
|
|
8668
|
-
}
|
|
8669
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkAvatar, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
8670
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkAvatar, isStandalone: true, selector: "bk-avatar", inputs: { src: "src", alt: "alt", name: "name", initialsOverride: "initialsOverride", tooltipContent: "tooltipContent", bgColor: "bgColor", textColor: "textColor", size: "size", variant: "variant", fallback: "fallback", dot: "dot", dotPosition: "dotPosition" }, outputs: { imageLoadError: "imageLoadError" }, providers: [
|
|
8671
|
-
{
|
|
8672
|
-
provide: NG_VALUE_ACCESSOR,
|
|
8673
|
-
useExisting: forwardRef(() => BkAvatar),
|
|
8674
|
-
multi: true
|
|
8675
|
-
}
|
|
8676
|
-
], usesOnChanges: true, ngImport: i0, template: "<div\r\n [ngClass]=\"containerClasses\"\r\n [ngStyle]=\"containerStyles\"\r\n [bkTooltip]=\"resolvedTooltip\"\r\n [bkTooltipPosition]=\"'top'\"\r\n>\r\n\r\n @if (showImage) {\r\n <img\r\n [src]=\"src\"\r\n [alt]=\"alt\"\r\n class=\"avatar-img\"\r\n (error)=\"onImageError()\"\r\n />\r\n }\r\n\r\n @else if (showInitials) {\r\n <span class=\"avatar-text\">\r\n {{ initials }}\r\n </span>\r\n }\r\n\r\n @else {\r\n <svg\r\n class=\"placeholder-icon\"\r\n viewBox=\"0 0 32 32\"\r\n fill=\"none\"\r\n aria-hidden=\"true\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M16 16c3.682 0 6.667-2.985 6.667-6.667S19.682 2.667 16 2.667 9.333 5.651 9.333 9.333 12.318 16 16 16Z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M27.453 29.333C27.453 24.173 22.32 20 16 20S4.547 24.173 4.547 29.333\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (dot !== 'none') {\r\n <span [ngClass]=\"dotClasses\"></span>\r\n }\r\n\r\n</div>\r\n", styles: [".avatar{@apply relative inline-flex items-center justify-center rounded-full flex-shrink-0 select-none transition-all duration-200;}.avatar-img{@apply w-full h-full object-cover rounded-full;}.avatar-text{@apply font-medium;}.avatar.xsm{@apply size-6 text-[10px] leading-[14px];}.avatar.sm{@apply size-8 text-sm;}.avatar.md{@apply size-10 text-base;}.avatar.lg{@apply size-12 text-[18px] leading-[26px];}.avatar.xl{@apply size-14 text-xl;}.avatar.xxl{@apply size-16 text-xl;}.avatar.xsm .placeholder-icon{@apply size-4;}.avatar.sm .placeholder-icon{@apply size-5;}.avatar.md .placeholder-icon{@apply size-6;}.avatar.lg .placeholder-icon{@apply size-7;}.avatar.xl .placeholder-icon,.avatar.xxl .placeholder-icon{@apply size-8;}.avatar-dot{@apply absolute rounded-full block box-content border-[1.5px] border-white;}.avatar.xsm .avatar-dot{@apply size-1;}.avatar.sm .avatar-dot{@apply size-1.5;}.avatar.md .avatar-dot{@apply size-2.5;}.avatar.lg .avatar-dot{@apply size-3;}.avatar.xl .avatar-dot{@apply size-[14px];}.avatar.xxl .avatar-dot{@apply size-4;}.avatar .active{@apply bg-[#22973F];}.avatar .inactive{@apply bg-gray-300;}.avatar .notification{@apply bg-[#2E90FA];}.avatar .none{@apply hidden;}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition", "bkTooltipScrollable", "bkTooltipMaxHeight", "bkTooltipSize", "bkTooltipAutoHeight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
8677
|
-
}
|
|
8678
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkAvatar, decorators: [{
|
|
8679
|
-
type: Component,
|
|
8680
|
-
args: [{ selector: 'bk-avatar', standalone: true, imports: [CommonModule, BKTooltipDirective], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
8681
|
-
{
|
|
8682
|
-
provide: NG_VALUE_ACCESSOR,
|
|
8683
|
-
useExisting: forwardRef(() => BkAvatar),
|
|
8684
|
-
multi: true
|
|
8685
|
-
}
|
|
8686
|
-
], template: "<div\r\n [ngClass]=\"containerClasses\"\r\n [ngStyle]=\"containerStyles\"\r\n [bkTooltip]=\"resolvedTooltip\"\r\n [bkTooltipPosition]=\"'top'\"\r\n>\r\n\r\n @if (showImage) {\r\n <img\r\n [src]=\"src\"\r\n [alt]=\"alt\"\r\n class=\"avatar-img\"\r\n (error)=\"onImageError()\"\r\n />\r\n }\r\n\r\n @else if (showInitials) {\r\n <span class=\"avatar-text\">\r\n {{ initials }}\r\n </span>\r\n }\r\n\r\n @else {\r\n <svg\r\n class=\"placeholder-icon\"\r\n viewBox=\"0 0 32 32\"\r\n fill=\"none\"\r\n aria-hidden=\"true\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M16 16c3.682 0 6.667-2.985 6.667-6.667S19.682 2.667 16 2.667 9.333 5.651 9.333 9.333 12.318 16 16 16Z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n <path\r\n d=\"M27.453 29.333C27.453 24.173 22.32 20 16 20S4.547 24.173 4.547 29.333\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n }\r\n\r\n @if (dot !== 'none') {\r\n <span [ngClass]=\"dotClasses\"></span>\r\n }\r\n\r\n</div>\r\n", styles: [".avatar{@apply relative inline-flex items-center justify-center rounded-full flex-shrink-0 select-none transition-all duration-200;}.avatar-img{@apply w-full h-full object-cover rounded-full;}.avatar-text{@apply font-medium;}.avatar.xsm{@apply size-6 text-[10px] leading-[14px];}.avatar.sm{@apply size-8 text-sm;}.avatar.md{@apply size-10 text-base;}.avatar.lg{@apply size-12 text-[18px] leading-[26px];}.avatar.xl{@apply size-14 text-xl;}.avatar.xxl{@apply size-16 text-xl;}.avatar.xsm .placeholder-icon{@apply size-4;}.avatar.sm .placeholder-icon{@apply size-5;}.avatar.md .placeholder-icon{@apply size-6;}.avatar.lg .placeholder-icon{@apply size-7;}.avatar.xl .placeholder-icon,.avatar.xxl .placeholder-icon{@apply size-8;}.avatar-dot{@apply absolute rounded-full block box-content border-[1.5px] border-white;}.avatar.xsm .avatar-dot{@apply size-1;}.avatar.sm .avatar-dot{@apply size-1.5;}.avatar.md .avatar-dot{@apply size-2.5;}.avatar.lg .avatar-dot{@apply size-3;}.avatar.xl .avatar-dot{@apply size-[14px];}.avatar.xxl .avatar-dot{@apply size-4;}.avatar .active{@apply bg-[#22973F];}.avatar .inactive{@apply bg-gray-300;}.avatar .notification{@apply bg-[#2E90FA];}.avatar .none{@apply hidden;}\n"] }]
|
|
8687
|
-
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { src: [{
|
|
8688
|
-
type: Input
|
|
8689
|
-
}], alt: [{
|
|
8690
|
-
type: Input
|
|
8691
|
-
}], name: [{
|
|
8692
|
-
type: Input
|
|
8693
|
-
}], initialsOverride: [{
|
|
8694
|
-
type: Input
|
|
8695
|
-
}], tooltipContent: [{
|
|
8696
|
-
type: Input
|
|
8697
|
-
}], bgColor: [{
|
|
8698
|
-
type: Input
|
|
8699
|
-
}], textColor: [{
|
|
8700
|
-
type: Input
|
|
8701
|
-
}], size: [{
|
|
8702
|
-
type: Input
|
|
8703
|
-
}], variant: [{
|
|
8704
|
-
type: Input
|
|
8705
|
-
}], fallback: [{
|
|
8706
|
-
type: Input
|
|
8707
|
-
}], dot: [{
|
|
8708
|
-
type: Input
|
|
8709
|
-
}], dotPosition: [{
|
|
8710
|
-
type: Input
|
|
8711
|
-
}], imageLoadError: [{
|
|
8712
|
-
type: Output
|
|
8713
|
-
}] } });
|
|
8714
|
-
// ---------- Constants ----------
|
|
8715
|
-
const VARIANT_MAP = {
|
|
8716
|
-
gray: 'bg-white border border-[#EFEFF1] text-[#363C51]',
|
|
8717
|
-
colored: 'bg-[#F63D68] border border-white text-white'
|
|
8718
|
-
};
|
|
8719
|
-
const DOT_COLOR_MAP = {
|
|
8720
|
-
active: 'active',
|
|
8721
|
-
inactive: 'inactive',
|
|
8722
|
-
notification: 'notification',
|
|
8723
|
-
none: 'hidden'
|
|
8724
|
-
};
|
|
8725
|
-
const DOT_POSITION_MAP = {
|
|
8726
|
-
'bottom-right': 'bottom-0 right-0',
|
|
8727
|
-
'top-left': 'top-0.5 -left-0.5'
|
|
8728
|
-
};
|
|
8729
|
-
|
|
8730
8998
|
class ColumnFilterOption {
|
|
8731
8999
|
columnName;
|
|
8732
9000
|
selected = true;
|
|
@@ -8899,7 +9167,7 @@ class BkColumnSelect {
|
|
|
8899
9167
|
useExisting: forwardRef(() => BkColumnSelect),
|
|
8900
9168
|
multi: true,
|
|
8901
9169
|
},
|
|
8902
|
-
], viewQueries: [{ propertyName: "formBoxRef", first: true, predicate: ["formBox"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"relative\">\r\n\r\n <bk-button [size]=\"'xsm'\" [variant]=\"'secondary'\" [leftIcon]=\"lefticon\"\r\n (click)=\"filterButtonClicked($event)\" [label]=\"label\" [buttonClass]=\"`text-black ${buttonClass}`\"></bk-button>\r\n\r\n <!-- Dropdown Box -->\r\n @if(isOpened){\r\n\r\n <div #formBox\r\n class=\"absolute right-0 mt-2 w-[178px] bg-white border border-[#EFEFF1] rounded-xl shadow-xl p-3 pe-1 z-[9999]\">\r\n @if(searchable){\r\n <bk-input [id]=\"'search-input-1'\" [name]=\"'search-input-1'\"\r\n [iconSrc]=\"'../../../../assets/icons/search-input.svg'\" type=\"text\" [(ngModel)]=\"search\"\r\n placeholder=\"Search\"></bk-input>\r\n }\r\n <div class=\"column-select-options-list\">\r\n @for (column of list; track column.columnName; let i = $index) {\r\n <div class=\"flex items-center gap-2 px-3 py-2\">\r\n <bk-checkbox [label]=\"column.columnName\" id=\"columnsFilterList-{{column.columnName}}\" checkboxClass=\"sm\" [(ngModel)]=\"column.selected\" labelClass=\"!text-left\"\r\n (change)=\"onChangeColumnFilter()\">\r\n\r\n </bk-checkbox>\r\n\r\n <!-- <label class=\"text-xs cursor-pointer text-[#141414] select-none truncate font-medium\"\r\n for=\"columnsFilterList-{{column.columnName}}\">\r\n {{column.columnName}}\r\n </label> -->\r\n\r\n </div>\r\n }\r\n @if(!list.length){\r\n <p class=\"column-select-option-empty\">No records found</p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".column-select-option-empty{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}.column-select-options-list{display:flex;flex-direction:column;overflow-y:auto}@media (max-height: 700px){.column-select-options-list{max-height:125px}}@media (min-height: 701px) and (max-height: 900px){.column-select-options-list{max-height:166px}}@media (min-height: 901px){.column-select-options-list{max-height:210px}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type:
|
|
9170
|
+
], viewQueries: [{ propertyName: "formBoxRef", first: true, predicate: ["formBox"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"relative\">\r\n\r\n <bk-button [size]=\"'xsm'\" [variant]=\"'secondary'\" [leftIcon]=\"lefticon\"\r\n (click)=\"filterButtonClicked($event)\" [label]=\"label\" [buttonClass]=\"`text-black ${buttonClass}`\"></bk-button>\r\n\r\n <!-- Dropdown Box -->\r\n @if(isOpened){\r\n\r\n <div #formBox\r\n class=\"absolute right-0 mt-2 w-[178px] bg-white border border-[#EFEFF1] rounded-xl shadow-xl p-3 pe-1 z-[9999]\">\r\n @if(searchable){\r\n <bk-input [id]=\"'search-input-1'\" [name]=\"'search-input-1'\"\r\n [iconSrc]=\"'../../../../assets/icons/search-input.svg'\" type=\"text\" [(ngModel)]=\"search\"\r\n placeholder=\"Search\"></bk-input>\r\n }\r\n <div class=\"column-select-options-list\">\r\n @for (column of list; track column.columnName; let i = $index) {\r\n <div class=\"flex items-center gap-2 px-3 py-2\">\r\n <bk-checkbox [label]=\"column.columnName\" id=\"columnsFilterList-{{column.columnName}}\" checkboxClass=\"sm\" [(ngModel)]=\"column.selected\" labelClass=\"!text-left\"\r\n (change)=\"onChangeColumnFilter()\">\r\n\r\n </bk-checkbox>\r\n\r\n <!-- <label class=\"text-xs cursor-pointer text-[#141414] select-none truncate font-medium\"\r\n for=\"columnsFilterList-{{column.columnName}}\">\r\n {{column.columnName}}\r\n </label> -->\r\n\r\n </div>\r\n }\r\n @if(!list.length){\r\n <p class=\"column-select-option-empty\">No records found</p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".column-select-option-empty{@apply px-3 py-2 text-gray-400 cursor-default text-sm;}.column-select-options-list{display:flex;flex-direction:column;overflow-y:auto}@media (max-height: 700px){.column-select-options-list{max-height:125px}}@media (min-height: 701px) and (max-height: 900px){.column-select-options-list{max-height:166px}}@media (min-height: 901px){.column-select-options-list{max-height:210px}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BkButton, selector: "bk-button", inputs: ["variant", "size", "shadow", "label", "leftIcon", "rightIcon", "iconAlt", "type", "loading", "disabled", "buttonClass", "textClass", "spinnerClass"], outputs: ["clicked"] }, { kind: "component", type: BkCheckbox, selector: "bk-checkbox", inputs: ["checkboxClass", "label", "labelClass", "disabled"], outputs: ["change"] }, { kind: "component", type: BkInput, selector: "bk-input", inputs: ["id", "name", "mask", "dropSpecialCharacters", "autoComplete", "label", "placeholder", "hint", "required", "type", "value", "hasError", "showErrorIcon", "errorMessage", "disabled", "tabIndex", "readOnly", "autoCapitalize", "inputMode", "iconSrc", "iconAlt", "showIcon", "phone", "countryCode", "countryOptions", "iconOrientation", "password", "showPassword", "pattern", "max", "min", "step", "maxlength", "minlength"], outputs: ["input", "change", "focus", "blur", "clicked"] }] });
|
|
8903
9171
|
}
|
|
8904
9172
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkColumnSelect, decorators: [{
|
|
8905
9173
|
type: Component,
|
|
@@ -9308,7 +9576,7 @@ class BkPagination {
|
|
|
9308
9576
|
return this.getPageCount();
|
|
9309
9577
|
}
|
|
9310
9578
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkPagination, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9311
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkPagination, isStandalone: true, selector: "bk-pagination", inputs: { pageSize: "pageSize", total: "total", activePage: "activePage" }, outputs: { changePageSize: "changePageSize", pageChanged: "pageChanged", activePageChange: "activePageChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"md:px-4 px-2 md:py-3 py-2 border-t border-[#EBEDF3] rounded-b-xl\">\r\n <div class=\"flex flex-row items-center justify-between md:gap-3 gap-1\">\r\n\r\n <!-- Page size dropdown -->\r\n\r\n\r\n <div class=\"flex gap-3 items-center pagination\">\r\n <p class=\"text-xs text-[#141414] font-medium md:block hidden\">Rows per page</p>\r\n <bk-select\r\n [items]=\"pageSizesList\"\r\n [searchable]=\"false\"\r\n bindLabel=\"key\"\r\n bindValue=\"value\"\r\n [clearable]=\"false\"\r\n [(ngModel)]=\"pageSize\"\r\n [dropdownPosition]=\"'top'\"\r\n (change)=\"changeSize($event)\"\r\n [variation]=\"'sm'\"\r\n [isResponsive]=\"false\"\r\n class=\"!min-w-[90px] lg:!min-w-[131px]\"\r\n >\r\n </bk-select>\r\n </div>\r\n\r\n <!-- showing entries -->\r\n <p class=\"text-xs text-[#141414] font-medium md:block hidden\">\r\n Showing <span>{{ startIndex }}</span> to\r\n <span>{{ endIndex > totalItems ? totalItems : endIndex }}</span> of\r\n <span>{{ totalItems }}</span> Records\r\n </p>\r\n\r\n <!-- Pagination main -->\r\n <nav class=\"flex gap-1.5 items-center\">\r\n\r\n <!-- Page count (optional like DoPlanar top numbers) -->\r\n <p class=\"text-xs text-[#141414] font-medium md:block hidden\">\r\n <span>{{ startingPage || 0 }}</span> -\r\n <span>{{ endingPage || 0 }}</span> of\r\n <span>{{ getTotalPages() || 0 }}</span>\r\n </p>\r\n\r\n\r\n <!-- Page count (optional like DoPlanar top numbers) mobile version -->\r\n <p class=\"text-xs text-[#141414] font-medium md:hidden block\">\r\n <span>{{ startingPage || 0 }}</span> -\r\n <span>{{ endingPage || 0 }}</span> of\r\n <span>{{ getTotalPages() || 0 }}</span>\r\n </p>\r\n\r\n <ul class=\"flex items-center space-x-1 text-[13px] text-[#B9BBC6]\">\r\n\r\n <!-- Previous -->\r\n <li class=\"md:block hidden\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n (click)=\"onClickPage(1)\"\r\n class=\"flex items-center justify-center md:size-7 size-6 text-[13px] leading-6 text-[#15191E] rounded-md hover:bg-[#F8F8FA]\"\r\n [ngClass]=\"{'cursor-not-allowed': activePage === 1}\"\r\n >\r\n @if(activePage === 1){\r\n <img\r\n src=\"../../assets/icons/arrow-left-double-gray.svg\"\r\n alt=\"Left Arrow Disabled\"\r\n />\r\n }\r\n @if(activePage !== 1){\r\n <img\r\n src=\"../../assets/icons/arrow-left-double-black.svg\"\r\n alt=\"Left Arrow\"\r\n />\r\n }\r\n </a>\r\n </li>\r\n <!-- Previous -->\r\n <li>\r\n <a\r\n href=\"javascript:void(0)\"\r\n (click)=\"onClickPage(activePage - 1)\"\r\n class=\"flex items-center justify-center md:size-7 size-6 text-[13px] leading-6 text-[#15191E] rounded-md hover:bg-[#F8F8FA]\"\r\n [ngClass]=\"{'cursor-not-allowed': activePage === 1}\"\r\n >\r\n @if(activePage === 1){\r\n <img\r\n src=\"../../assets/icons/pagination-left-gray.svg\"\r\n alt=\"Left Arrow Disabled\"\r\n />\r\n }\r\n @if(activePage !== 1){\r\n <img\r\n src=\"../../assets/icons/pagination-left-black.svg\"\r\n alt=\"Left Arrow\"\r\n />\r\n }\r\n </a>\r\n </li>\r\n\r\n <!-- Page Numbers -->\r\n <li *ngFor=\"let item of paginate()\">\r\n <a\r\n (click)=\"onClickPage(item)\"\r\n href=\"javascript:void(0)\"\r\n class=\"flex items-center justify-center md:size-7 size-6 leading-6 rounded-lg\"\r\n [ngClass]=\"item === activePage\r\n ? 'text-[#15191E] bg-[#F8F8FA] hover:bg-[#F8F8FA]'\r\n : 'hover:bg-[#F8F8FA] hover:text-[#15191E]'\">\r\n {{ item }}\r\n </a>\r\n </li>\r\n\r\n <!-- Next -->\r\n <li>\r\n <a\r\n href=\"javascript:void(0)\"\r\n (click)=\"onClickPage(activePage + 1)\"\r\n class=\"flex items-center justify-center md:size-7 size-6 text-[13px] leading-6 text-[#15191E] rounded-md hover:bg-[#F8F8FA]\"\r\n [ngClass]=\"{'cursor-not-allowed': activePage === getTotalPages()}\"\r\n >\r\n @if(activePage === getTotalPages()){\r\n <img\r\n src=\"../../assets/icons/pagination-right-gray.svg\"\r\n alt=\"Right Arrow Disabled\"\r\n />\r\n }\r\n @if(activePage !== getTotalPages()){\r\n <img\r\n src=\"../../assets/icons/pagination-right-black.svg\"\r\n alt=\"Right Arrow\"\r\n />\r\n }\r\n </a>\r\n </li>\r\n <!-- next double arrow -->\r\n <li class=\"md:block hidden\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n (click)=\"onClickPage(getTotalPages())\"\r\n class=\"flex items-center justify-center md:size-7 size-6 text-[13px] leading-6 text-[#15191E] rounded-md hover:bg-[#F8F8FA]\"\r\n [ngClass]=\"{'cursor-not-allowed': activePage === getTotalPages()}\"\r\n >\r\n @if(activePage === getTotalPages()){\r\n <img\r\n src=\"../../assets/icons/arrow-right-double-gray.svg\"\r\n alt=\"Right Arrow Disabled\"\r\n />\r\n }\r\n @if(activePage !== getTotalPages()){\r\n <img\r\n src=\"../../assets/icons/arrow-right-double-black.svg\"\r\n alt=\"Right Arrow\"\r\n />\r\n }\r\n </a>\r\n </li>\r\n </ul>\r\n </nav>\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type:
|
|
9579
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkPagination, isStandalone: true, selector: "bk-pagination", inputs: { pageSize: "pageSize", total: "total", activePage: "activePage" }, outputs: { changePageSize: "changePageSize", pageChanged: "pageChanged", activePageChange: "activePageChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"md:px-4 px-2 md:py-3 py-2 border-t border-[#EBEDF3] rounded-b-xl\">\r\n <div class=\"flex flex-row items-center justify-between md:gap-3 gap-1\">\r\n\r\n <!-- Page size dropdown -->\r\n\r\n\r\n <div class=\"flex gap-3 items-center pagination\">\r\n <p class=\"text-xs text-[#141414] font-medium md:block hidden\">Rows per page</p>\r\n <bk-select\r\n [items]=\"pageSizesList\"\r\n [searchable]=\"false\"\r\n bindLabel=\"key\"\r\n bindValue=\"value\"\r\n [clearable]=\"false\"\r\n [(ngModel)]=\"pageSize\"\r\n [dropdownPosition]=\"'top'\"\r\n (change)=\"changeSize($event)\"\r\n [variation]=\"'sm'\"\r\n [isResponsive]=\"false\"\r\n class=\"!min-w-[90px] lg:!min-w-[131px]\"\r\n >\r\n </bk-select>\r\n </div>\r\n\r\n <!-- showing entries -->\r\n <p class=\"text-xs text-[#141414] font-medium md:block hidden\">\r\n Showing <span>{{ startIndex }}</span> to\r\n <span>{{ endIndex > totalItems ? totalItems : endIndex }}</span> of\r\n <span>{{ totalItems }}</span> Records\r\n </p>\r\n\r\n <!-- Pagination main -->\r\n <nav class=\"flex gap-1.5 items-center\">\r\n\r\n <!-- Page count (optional like DoPlanar top numbers) -->\r\n <p class=\"text-xs text-[#141414] font-medium md:block hidden\">\r\n <span>{{ startingPage || 0 }}</span> -\r\n <span>{{ endingPage || 0 }}</span> of\r\n <span>{{ getTotalPages() || 0 }}</span>\r\n </p>\r\n\r\n\r\n <!-- Page count (optional like DoPlanar top numbers) mobile version -->\r\n <p class=\"text-xs text-[#141414] font-medium md:hidden block\">\r\n <span>{{ startingPage || 0 }}</span> -\r\n <span>{{ endingPage || 0 }}</span> of\r\n <span>{{ getTotalPages() || 0 }}</span>\r\n </p>\r\n\r\n <ul class=\"flex items-center space-x-1 text-[13px] text-[#B9BBC6]\">\r\n\r\n <!-- Previous -->\r\n <li class=\"md:block hidden\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n (click)=\"onClickPage(1)\"\r\n class=\"flex items-center justify-center md:size-7 size-6 text-[13px] leading-6 text-[#15191E] rounded-md hover:bg-[#F8F8FA]\"\r\n [ngClass]=\"{'cursor-not-allowed': activePage === 1}\"\r\n >\r\n @if(activePage === 1){\r\n <img\r\n src=\"../../assets/icons/arrow-left-double-gray.svg\"\r\n alt=\"Left Arrow Disabled\"\r\n />\r\n }\r\n @if(activePage !== 1){\r\n <img\r\n src=\"../../assets/icons/arrow-left-double-black.svg\"\r\n alt=\"Left Arrow\"\r\n />\r\n }\r\n </a>\r\n </li>\r\n <!-- Previous -->\r\n <li>\r\n <a\r\n href=\"javascript:void(0)\"\r\n (click)=\"onClickPage(activePage - 1)\"\r\n class=\"flex items-center justify-center md:size-7 size-6 text-[13px] leading-6 text-[#15191E] rounded-md hover:bg-[#F8F8FA]\"\r\n [ngClass]=\"{'cursor-not-allowed': activePage === 1}\"\r\n >\r\n @if(activePage === 1){\r\n <img\r\n src=\"../../assets/icons/pagination-left-gray.svg\"\r\n alt=\"Left Arrow Disabled\"\r\n />\r\n }\r\n @if(activePage !== 1){\r\n <img\r\n src=\"../../assets/icons/pagination-left-black.svg\"\r\n alt=\"Left Arrow\"\r\n />\r\n }\r\n </a>\r\n </li>\r\n\r\n <!-- Page Numbers -->\r\n <li *ngFor=\"let item of paginate()\">\r\n <a\r\n (click)=\"onClickPage(item)\"\r\n href=\"javascript:void(0)\"\r\n class=\"flex items-center justify-center md:size-7 size-6 leading-6 rounded-lg\"\r\n [ngClass]=\"item === activePage\r\n ? 'text-[#15191E] bg-[#F8F8FA] hover:bg-[#F8F8FA]'\r\n : 'hover:bg-[#F8F8FA] hover:text-[#15191E]'\">\r\n {{ item }}\r\n </a>\r\n </li>\r\n\r\n <!-- Next -->\r\n <li>\r\n <a\r\n href=\"javascript:void(0)\"\r\n (click)=\"onClickPage(activePage + 1)\"\r\n class=\"flex items-center justify-center md:size-7 size-6 text-[13px] leading-6 text-[#15191E] rounded-md hover:bg-[#F8F8FA]\"\r\n [ngClass]=\"{'cursor-not-allowed': activePage === getTotalPages()}\"\r\n >\r\n @if(activePage === getTotalPages()){\r\n <img\r\n src=\"../../assets/icons/pagination-right-gray.svg\"\r\n alt=\"Right Arrow Disabled\"\r\n />\r\n }\r\n @if(activePage !== getTotalPages()){\r\n <img\r\n src=\"../../assets/icons/pagination-right-black.svg\"\r\n alt=\"Right Arrow\"\r\n />\r\n }\r\n </a>\r\n </li>\r\n <!-- next double arrow -->\r\n <li class=\"md:block hidden\">\r\n <a\r\n href=\"javascript:void(0)\"\r\n (click)=\"onClickPage(getTotalPages())\"\r\n class=\"flex items-center justify-center md:size-7 size-6 text-[13px] leading-6 text-[#15191E] rounded-md hover:bg-[#F8F8FA]\"\r\n [ngClass]=\"{'cursor-not-allowed': activePage === getTotalPages()}\"\r\n >\r\n @if(activePage === getTotalPages()){\r\n <img\r\n src=\"../../assets/icons/arrow-right-double-gray.svg\"\r\n alt=\"Right Arrow Disabled\"\r\n />\r\n }\r\n @if(activePage !== getTotalPages()){\r\n <img\r\n src=\"../../assets/icons/arrow-right-double-black.svg\"\r\n alt=\"Right Arrow\"\r\n />\r\n }\r\n </a>\r\n </li>\r\n </ul>\r\n </nav>\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BkSelect, selector: "bk-select", inputs: ["items", "bindLabel", "bindValue", "bindIcon", "isResponsive", "placeholder", "notFoundText", "loadingText", "clearAllText", "groupBy", "colorKey", "showDots", "showAvatar", "avatarKey", "iconAlt", "label", "required", "variation", "iconSrc", "multiple", "maxLabels", "searchable", "allSelect", "clearable", "readonly", "disabled", "loading", "closeOnSelect", "dropdownPosition", "hasError", "errorMessage", "appendToBody", "compareWith"], outputs: ["disabledChange", "open", "close", "focus", "blur", "search", "clear", "change", "scrollToEnd"] }] });
|
|
9312
9580
|
}
|
|
9313
9581
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkPagination, decorators: [{
|
|
9314
9582
|
type: Component,
|
|
@@ -9728,11 +9996,11 @@ class BkMenu {
|
|
|
9728
9996
|
}
|
|
9729
9997
|
}
|
|
9730
9998
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkMenu, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
9731
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkMenu, isStandalone: true, selector: "bk-menu", inputs: { items: "items", orientation: "orientation", submenuMode: "submenuMode", singleOpen: "singleOpen", activeItemId: "activeItemId", tintIcons: "tintIcons", maxHeight: "maxHeight" }, outputs: { activeItemIdChange: "activeItemIdChange", itemClick: "itemClick" }, host: { listeners: { "document:click": "onDocumentClick($event)", "window:scroll": "onViewportChange()", "window:resize": "onViewportChange()" } }, ngImport: i0, template: "<nav\r\n class=\"bk-menu\"\r\n [class.bk-menu--vertical]=\"isVertical\"\r\n [class.bk-menu--horizontal]=\"!isVertical\"\r\n [class.bk-menu--popup]=\"isPopup\"\r\n [class.bk-menu--tint]=\"tintIcons\"\r\n role=\"menubar\"\r\n [attr.aria-orientation]=\"orientation\">\r\n <ul\r\n class=\"bk-menu__list\"\r\n [class.bk-menu__list--scroll]=\"maxHeightStyle\"\r\n [style.maxHeight]=\"maxHeightStyle\">\r\n <ng-container *ngTemplateOutlet=\"itemTpl; context: { $implicit: items, level: 0 }\"></ng-container>\r\n </ul>\r\n</nav>\r\n\r\n<!-- Recursive item renderer. Context: $implicit = items at this level, level = depth. -->\r\n<ng-template #itemTpl let-items let-level=\"level\">\r\n @for (item of items; track item.id) {\r\n <li\r\n class=\"bk-menu__item\"\r\n [class.bk-menu__item--has-children]=\"hasChildren(item)\"\r\n [class.bk-menu__item--open]=\"isOpen(item)\"\r\n (mouseenter)=\"onItemEnter(item, items, $event, level)\"\r\n (mouseleave)=\"onItemLeave(item)\"\r\n role=\"none\">\r\n <button\r\n type=\"button\"\r\n class=\"bk-menu__button\"\r\n [class.bk-menu__button--active]=\"isHighlighted(item)\"\r\n [class.bk-menu__button--disabled]=\"item.disabled\"\r\n [class.bk-menu__button--parent]=\"hasChildren(item)\"\r\n [style.paddingLeft.px]=\"inlineIndent(level)\"\r\n [disabled]=\"item.disabled\"\r\n [attr.aria-haspopup]=\"hasChildren(item) ? 'true' : null\"\r\n [attr.aria-expanded]=\"hasChildren(item) ? isOpen(item) : null\"\r\n role=\"menuitem\"\r\n (click)=\"onItemClick(item, items, $event)\">\r\n @if (item.icon) {\r\n <img class=\"bk-menu__icon\" [attr.src]=\"item.icon\" [alt]=\"item.iconAlt || item.label\" />\r\n }\r\n <span class=\"bk-menu__label\">{{ item.label }}</span>\r\n @if (hasChildren(item)) {\r\n <svg\r\n class=\"bk-menu__chevron\"\r\n [class.bk-menu__chevron--open]=\"!isPopup && isOpen(item)\"\r\n [class.bk-menu__chevron--right]=\"isPopup && (isVertical || level > 0)\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"16\"\r\n height=\"16\"\r\n fill=\"none\"\r\n aria-hidden=\"true\">\r\n <path d=\"M6 9L12 15L18 9\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n }\r\n </button>\r\n\r\n @if (hasChildren(item)) {\r\n <ul\r\n class=\"bk-menu__submenu\"\r\n [class.bk-menu__submenu--inline]=\"!isPopup\"\r\n [class.bk-menu__submenu--popup]=\"isPopup\"\r\n [class.bk-menu__submenu--open]=\"isOpen(item)\"\r\n [class.bk-menu__submenu--popup-right]=\"isPopup && (isVertical || level > 0)\"\r\n [class.bk-menu__submenu--popup-down]=\"isPopup && !isVertical && level === 0\"\r\n [style.top.px]=\"popupTop(item)\"\r\n [style.left.px]=\"popupLeft(item)\"\r\n role=\"menu\">\r\n <ng-container\r\n *ngTemplateOutlet=\"itemTpl; context: { $implicit: item.children, level: level + 1 }\">\r\n </ng-container>\r\n </ul>\r\n }\r\n </li>\r\n }\r\n</ng-template>\r\n", styles: [".bk-menu{--menu-bg: #ffffff;--menu-text: #141414;--menu-subtext: #6b7080;--menu-hover-bg: #edeef0;--menu-hover-text: #141414;--menu-active-bg: #141414;--menu-active-text: #ffffff;--menu-border: #efeff1;--menu-shadow: 0 7px 18px 0 rgba(0, 0, 0, .09);--menu-radius: 8px;--menu-disabled: .5
|
|
9999
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkMenu, isStandalone: true, selector: "bk-menu", inputs: { items: "items", orientation: "orientation", submenuMode: "submenuMode", singleOpen: "singleOpen", activeItemId: "activeItemId", tintIcons: "tintIcons", maxHeight: "maxHeight" }, outputs: { activeItemIdChange: "activeItemIdChange", itemClick: "itemClick" }, host: { listeners: { "document:click": "onDocumentClick($event)", "window:scroll": "onViewportChange()", "window:resize": "onViewportChange()" } }, ngImport: i0, template: "<nav\r\n class=\"bk-menu\"\r\n [class.bk-menu--vertical]=\"isVertical\"\r\n [class.bk-menu--horizontal]=\"!isVertical\"\r\n [class.bk-menu--popup]=\"isPopup\"\r\n [class.bk-menu--tint]=\"tintIcons\"\r\n role=\"menubar\"\r\n [attr.aria-orientation]=\"orientation\">\r\n <ul\r\n class=\"bk-menu__list\"\r\n [class.bk-menu__list--scroll]=\"maxHeightStyle\"\r\n [style.maxHeight]=\"maxHeightStyle\">\r\n <ng-container *ngTemplateOutlet=\"itemTpl; context: { $implicit: items, level: 0 }\"></ng-container>\r\n </ul>\r\n</nav>\r\n\r\n<!-- Recursive item renderer. Context: $implicit = items at this level, level = depth. -->\r\n<ng-template #itemTpl let-items let-level=\"level\">\r\n @for (item of items; track item.id) {\r\n <li\r\n class=\"bk-menu__item\"\r\n [class.bk-menu__item--has-children]=\"hasChildren(item)\"\r\n [class.bk-menu__item--open]=\"isOpen(item)\"\r\n (mouseenter)=\"onItemEnter(item, items, $event, level)\"\r\n (mouseleave)=\"onItemLeave(item)\"\r\n role=\"none\">\r\n <button\r\n type=\"button\"\r\n class=\"bk-menu__button\"\r\n [class.bk-menu__button--active]=\"isHighlighted(item)\"\r\n [class.bk-menu__button--disabled]=\"item.disabled\"\r\n [class.bk-menu__button--parent]=\"hasChildren(item)\"\r\n [style.paddingLeft.px]=\"inlineIndent(level)\"\r\n [disabled]=\"item.disabled\"\r\n [attr.aria-haspopup]=\"hasChildren(item) ? 'true' : null\"\r\n [attr.aria-expanded]=\"hasChildren(item) ? isOpen(item) : null\"\r\n role=\"menuitem\"\r\n (click)=\"onItemClick(item, items, $event)\">\r\n @if (item.icon) {\r\n <img class=\"bk-menu__icon\" [attr.src]=\"item.icon\" [alt]=\"item.iconAlt || item.label\" />\r\n }\r\n <span class=\"bk-menu__label\">{{ item.label }}</span>\r\n @if (hasChildren(item)) {\r\n <svg\r\n class=\"bk-menu__chevron\"\r\n [class.bk-menu__chevron--open]=\"!isPopup && isOpen(item)\"\r\n [class.bk-menu__chevron--right]=\"isPopup && (isVertical || level > 0)\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"16\"\r\n height=\"16\"\r\n fill=\"none\"\r\n aria-hidden=\"true\">\r\n <path d=\"M6 9L12 15L18 9\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n }\r\n </button>\r\n\r\n @if (hasChildren(item)) {\r\n <ul\r\n class=\"bk-menu__submenu\"\r\n [class.bk-menu__submenu--inline]=\"!isPopup\"\r\n [class.bk-menu__submenu--popup]=\"isPopup\"\r\n [class.bk-menu__submenu--open]=\"isOpen(item)\"\r\n [class.bk-menu__submenu--popup-right]=\"isPopup && (isVertical || level > 0)\"\r\n [class.bk-menu__submenu--popup-down]=\"isPopup && !isVertical && level === 0\"\r\n [style.top.px]=\"popupTop(item)\"\r\n [style.left.px]=\"popupLeft(item)\"\r\n role=\"menu\">\r\n <ng-container\r\n *ngTemplateOutlet=\"itemTpl; context: { $implicit: item.children, level: level + 1 }\">\r\n </ng-container>\r\n </ul>\r\n }\r\n </li>\r\n }\r\n</ng-template>\r\n", styles: [".bk-menu{--menu-bg: #ffffff;--menu-text: #141414;--menu-subtext: #6b7080;--menu-hover-bg: #edeef0;--menu-hover-text: #141414;--menu-active-bg: #141414;--menu-active-text: #ffffff;--menu-border: #efeff1;--menu-shadow: 0 7px 18px 0 rgba(0, 0, 0, .09);--menu-radius: 8px;--menu-disabled: .5;@apply block w-full max-w-full text-sm font-medium tracking-[-.28px] bg-[var(--menu-bg)] text-[color:var(--menu-text)] border border-[var(--menu-border)] rounded-[var(--menu-radius)] overflow-hidden;}.bk-menu__list,.bk-menu__submenu{@apply list-none m-0 p-0;}.bk-menu__list--scroll{@apply overflow-auto;}.bk-menu--horizontal>.bk-menu__list{@apply flex flex-row items-stretch overflow-x-auto;}.bk-menu__item{@apply relative;}.bk-menu__button{@apply flex items-center gap-2 w-full py-2.5 px-3 m-0 border-0 bg-transparent text-inherit text-left cursor-pointer whitespace-nowrap transition-colors duration-100;font:inherit;letter-spacing:inherit}.bk-menu--horizontal>.bk-menu__list>.bk-menu__item>.bk-menu__button{@apply w-auto;}.bk-menu--vertical>.bk-menu__list>.bk-menu__item:first-child>.bk-menu__button{@apply rounded-t-[var(--menu-radius)];}.bk-menu--vertical>.bk-menu__list>.bk-menu__item:last-child>.bk-menu__button{@apply rounded-b-[var(--menu-radius)];}.bk-menu--horizontal>.bk-menu__list>.bk-menu__item:first-child>.bk-menu__button{@apply rounded-l-[var(--menu-radius)];}.bk-menu--horizontal>.bk-menu__list>.bk-menu__item:last-child>.bk-menu__button{@apply rounded-r-[var(--menu-radius)];}.bk-menu__button:hover:not(:disabled):not(.bk-menu__button--active){@apply bg-[var(--menu-hover-bg)] text-[color:var(--menu-hover-text)];}.bk-menu__button--active{@apply bg-[var(--menu-active-bg)] text-[color:var(--menu-active-text)];}.bk-menu__button--disabled,.bk-menu__button:disabled{@apply opacity-[var(--menu-disabled)] cursor-not-allowed;}.bk-menu__submenu .bk-menu__button{@apply text-[color:var(--menu-subtext)] font-normal;}.bk-menu__submenu .bk-menu__button--active{@apply text-[color:var(--menu-active-text)];}.bk-menu__icon{@apply w-4 h-4 shrink-0 object-contain;}.bk-menu--tint .bk-menu__icon{@apply [filter:brightness(0)_saturate(0)];}.bk-menu--tint .bk-menu__button--active .bk-menu__icon{@apply [filter:brightness(0)_invert(1)];}.bk-menu__label{@apply flex-auto min-w-0 overflow-hidden text-ellipsis;}.bk-menu--horizontal>.bk-menu__list>.bk-menu__item>.bk-menu__button>.bk-menu__label{@apply flex-none overflow-visible;}.bk-menu__chevron{@apply shrink-0 opacity-80 transition-transform duration-[.18s];}.bk-menu__chevron--open{@apply rotate-180;}.bk-menu__chevron--right{@apply -rotate-90;}.bk-menu__submenu--inline{@apply overflow-hidden max-h-0 transition-[max-height] duration-200;}.bk-menu__submenu--inline.bk-menu__submenu--open{@apply max-h-[1000px];}.bk-menu__submenu--popup{@apply fixed z-[1000] min-w-[200px] max-w-[280px] max-h-[100vh-16px] overflow-y-auto bg-[var(--menu-bg)] border border-[var(--menu-border)] rounded-xl shadow-[var(--menu-shadow)] p-1 hidden;}.bk-menu__submenu--popup.bk-menu__submenu--open{@apply block;}.bk-menu__submenu--popup-right:before{content:\"\";@apply absolute top-0 left-[-6px] w-1.5 h-full;}.bk-menu__submenu--popup-down:before{content:\"\";@apply absolute top-[-6px] left-0 w-full h-1.5;}@media (max-width: 640px){.bk-menu--horizontal>.bk-menu__list{@apply overflow-x-auto;-webkit-overflow-scrolling:touch}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
9732
10000
|
}
|
|
9733
10001
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkMenu, decorators: [{
|
|
9734
10002
|
type: Component,
|
|
9735
|
-
args: [{ selector: 'bk-menu', imports: [CommonModule], template: "<nav\r\n class=\"bk-menu\"\r\n [class.bk-menu--vertical]=\"isVertical\"\r\n [class.bk-menu--horizontal]=\"!isVertical\"\r\n [class.bk-menu--popup]=\"isPopup\"\r\n [class.bk-menu--tint]=\"tintIcons\"\r\n role=\"menubar\"\r\n [attr.aria-orientation]=\"orientation\">\r\n <ul\r\n class=\"bk-menu__list\"\r\n [class.bk-menu__list--scroll]=\"maxHeightStyle\"\r\n [style.maxHeight]=\"maxHeightStyle\">\r\n <ng-container *ngTemplateOutlet=\"itemTpl; context: { $implicit: items, level: 0 }\"></ng-container>\r\n </ul>\r\n</nav>\r\n\r\n<!-- Recursive item renderer. Context: $implicit = items at this level, level = depth. -->\r\n<ng-template #itemTpl let-items let-level=\"level\">\r\n @for (item of items; track item.id) {\r\n <li\r\n class=\"bk-menu__item\"\r\n [class.bk-menu__item--has-children]=\"hasChildren(item)\"\r\n [class.bk-menu__item--open]=\"isOpen(item)\"\r\n (mouseenter)=\"onItemEnter(item, items, $event, level)\"\r\n (mouseleave)=\"onItemLeave(item)\"\r\n role=\"none\">\r\n <button\r\n type=\"button\"\r\n class=\"bk-menu__button\"\r\n [class.bk-menu__button--active]=\"isHighlighted(item)\"\r\n [class.bk-menu__button--disabled]=\"item.disabled\"\r\n [class.bk-menu__button--parent]=\"hasChildren(item)\"\r\n [style.paddingLeft.px]=\"inlineIndent(level)\"\r\n [disabled]=\"item.disabled\"\r\n [attr.aria-haspopup]=\"hasChildren(item) ? 'true' : null\"\r\n [attr.aria-expanded]=\"hasChildren(item) ? isOpen(item) : null\"\r\n role=\"menuitem\"\r\n (click)=\"onItemClick(item, items, $event)\">\r\n @if (item.icon) {\r\n <img class=\"bk-menu__icon\" [attr.src]=\"item.icon\" [alt]=\"item.iconAlt || item.label\" />\r\n }\r\n <span class=\"bk-menu__label\">{{ item.label }}</span>\r\n @if (hasChildren(item)) {\r\n <svg\r\n class=\"bk-menu__chevron\"\r\n [class.bk-menu__chevron--open]=\"!isPopup && isOpen(item)\"\r\n [class.bk-menu__chevron--right]=\"isPopup && (isVertical || level > 0)\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"16\"\r\n height=\"16\"\r\n fill=\"none\"\r\n aria-hidden=\"true\">\r\n <path d=\"M6 9L12 15L18 9\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n }\r\n </button>\r\n\r\n @if (hasChildren(item)) {\r\n <ul\r\n class=\"bk-menu__submenu\"\r\n [class.bk-menu__submenu--inline]=\"!isPopup\"\r\n [class.bk-menu__submenu--popup]=\"isPopup\"\r\n [class.bk-menu__submenu--open]=\"isOpen(item)\"\r\n [class.bk-menu__submenu--popup-right]=\"isPopup && (isVertical || level > 0)\"\r\n [class.bk-menu__submenu--popup-down]=\"isPopup && !isVertical && level === 0\"\r\n [style.top.px]=\"popupTop(item)\"\r\n [style.left.px]=\"popupLeft(item)\"\r\n role=\"menu\">\r\n <ng-container\r\n *ngTemplateOutlet=\"itemTpl; context: { $implicit: item.children, level: level + 1 }\">\r\n </ng-container>\r\n </ul>\r\n }\r\n </li>\r\n }\r\n</ng-template>\r\n", styles: [".bk-menu{--menu-bg: #ffffff;--menu-text: #141414;--menu-subtext: #6b7080;--menu-hover-bg: #edeef0;--menu-hover-text: #141414;--menu-active-bg: #141414;--menu-active-text: #ffffff;--menu-border: #efeff1;--menu-shadow: 0 7px 18px 0 rgba(0, 0, 0, .09);--menu-radius: 8px;--menu-disabled: .5
|
|
10003
|
+
args: [{ selector: 'bk-menu', imports: [CommonModule], template: "<nav\r\n class=\"bk-menu\"\r\n [class.bk-menu--vertical]=\"isVertical\"\r\n [class.bk-menu--horizontal]=\"!isVertical\"\r\n [class.bk-menu--popup]=\"isPopup\"\r\n [class.bk-menu--tint]=\"tintIcons\"\r\n role=\"menubar\"\r\n [attr.aria-orientation]=\"orientation\">\r\n <ul\r\n class=\"bk-menu__list\"\r\n [class.bk-menu__list--scroll]=\"maxHeightStyle\"\r\n [style.maxHeight]=\"maxHeightStyle\">\r\n <ng-container *ngTemplateOutlet=\"itemTpl; context: { $implicit: items, level: 0 }\"></ng-container>\r\n </ul>\r\n</nav>\r\n\r\n<!-- Recursive item renderer. Context: $implicit = items at this level, level = depth. -->\r\n<ng-template #itemTpl let-items let-level=\"level\">\r\n @for (item of items; track item.id) {\r\n <li\r\n class=\"bk-menu__item\"\r\n [class.bk-menu__item--has-children]=\"hasChildren(item)\"\r\n [class.bk-menu__item--open]=\"isOpen(item)\"\r\n (mouseenter)=\"onItemEnter(item, items, $event, level)\"\r\n (mouseleave)=\"onItemLeave(item)\"\r\n role=\"none\">\r\n <button\r\n type=\"button\"\r\n class=\"bk-menu__button\"\r\n [class.bk-menu__button--active]=\"isHighlighted(item)\"\r\n [class.bk-menu__button--disabled]=\"item.disabled\"\r\n [class.bk-menu__button--parent]=\"hasChildren(item)\"\r\n [style.paddingLeft.px]=\"inlineIndent(level)\"\r\n [disabled]=\"item.disabled\"\r\n [attr.aria-haspopup]=\"hasChildren(item) ? 'true' : null\"\r\n [attr.aria-expanded]=\"hasChildren(item) ? isOpen(item) : null\"\r\n role=\"menuitem\"\r\n (click)=\"onItemClick(item, items, $event)\">\r\n @if (item.icon) {\r\n <img class=\"bk-menu__icon\" [attr.src]=\"item.icon\" [alt]=\"item.iconAlt || item.label\" />\r\n }\r\n <span class=\"bk-menu__label\">{{ item.label }}</span>\r\n @if (hasChildren(item)) {\r\n <svg\r\n class=\"bk-menu__chevron\"\r\n [class.bk-menu__chevron--open]=\"!isPopup && isOpen(item)\"\r\n [class.bk-menu__chevron--right]=\"isPopup && (isVertical || level > 0)\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"16\"\r\n height=\"16\"\r\n fill=\"none\"\r\n aria-hidden=\"true\">\r\n <path d=\"M6 9L12 15L18 9\" stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n }\r\n </button>\r\n\r\n @if (hasChildren(item)) {\r\n <ul\r\n class=\"bk-menu__submenu\"\r\n [class.bk-menu__submenu--inline]=\"!isPopup\"\r\n [class.bk-menu__submenu--popup]=\"isPopup\"\r\n [class.bk-menu__submenu--open]=\"isOpen(item)\"\r\n [class.bk-menu__submenu--popup-right]=\"isPopup && (isVertical || level > 0)\"\r\n [class.bk-menu__submenu--popup-down]=\"isPopup && !isVertical && level === 0\"\r\n [style.top.px]=\"popupTop(item)\"\r\n [style.left.px]=\"popupLeft(item)\"\r\n role=\"menu\">\r\n <ng-container\r\n *ngTemplateOutlet=\"itemTpl; context: { $implicit: item.children, level: level + 1 }\">\r\n </ng-container>\r\n </ul>\r\n }\r\n </li>\r\n }\r\n</ng-template>\r\n", styles: [".bk-menu{--menu-bg: #ffffff;--menu-text: #141414;--menu-subtext: #6b7080;--menu-hover-bg: #edeef0;--menu-hover-text: #141414;--menu-active-bg: #141414;--menu-active-text: #ffffff;--menu-border: #efeff1;--menu-shadow: 0 7px 18px 0 rgba(0, 0, 0, .09);--menu-radius: 8px;--menu-disabled: .5;@apply block w-full max-w-full text-sm font-medium tracking-[-.28px] bg-[var(--menu-bg)] text-[color:var(--menu-text)] border border-[var(--menu-border)] rounded-[var(--menu-radius)] overflow-hidden;}.bk-menu__list,.bk-menu__submenu{@apply list-none m-0 p-0;}.bk-menu__list--scroll{@apply overflow-auto;}.bk-menu--horizontal>.bk-menu__list{@apply flex flex-row items-stretch overflow-x-auto;}.bk-menu__item{@apply relative;}.bk-menu__button{@apply flex items-center gap-2 w-full py-2.5 px-3 m-0 border-0 bg-transparent text-inherit text-left cursor-pointer whitespace-nowrap transition-colors duration-100;font:inherit;letter-spacing:inherit}.bk-menu--horizontal>.bk-menu__list>.bk-menu__item>.bk-menu__button{@apply w-auto;}.bk-menu--vertical>.bk-menu__list>.bk-menu__item:first-child>.bk-menu__button{@apply rounded-t-[var(--menu-radius)];}.bk-menu--vertical>.bk-menu__list>.bk-menu__item:last-child>.bk-menu__button{@apply rounded-b-[var(--menu-radius)];}.bk-menu--horizontal>.bk-menu__list>.bk-menu__item:first-child>.bk-menu__button{@apply rounded-l-[var(--menu-radius)];}.bk-menu--horizontal>.bk-menu__list>.bk-menu__item:last-child>.bk-menu__button{@apply rounded-r-[var(--menu-radius)];}.bk-menu__button:hover:not(:disabled):not(.bk-menu__button--active){@apply bg-[var(--menu-hover-bg)] text-[color:var(--menu-hover-text)];}.bk-menu__button--active{@apply bg-[var(--menu-active-bg)] text-[color:var(--menu-active-text)];}.bk-menu__button--disabled,.bk-menu__button:disabled{@apply opacity-[var(--menu-disabled)] cursor-not-allowed;}.bk-menu__submenu .bk-menu__button{@apply text-[color:var(--menu-subtext)] font-normal;}.bk-menu__submenu .bk-menu__button--active{@apply text-[color:var(--menu-active-text)];}.bk-menu__icon{@apply w-4 h-4 shrink-0 object-contain;}.bk-menu--tint .bk-menu__icon{@apply [filter:brightness(0)_saturate(0)];}.bk-menu--tint .bk-menu__button--active .bk-menu__icon{@apply [filter:brightness(0)_invert(1)];}.bk-menu__label{@apply flex-auto min-w-0 overflow-hidden text-ellipsis;}.bk-menu--horizontal>.bk-menu__list>.bk-menu__item>.bk-menu__button>.bk-menu__label{@apply flex-none overflow-visible;}.bk-menu__chevron{@apply shrink-0 opacity-80 transition-transform duration-[.18s];}.bk-menu__chevron--open{@apply rotate-180;}.bk-menu__chevron--right{@apply -rotate-90;}.bk-menu__submenu--inline{@apply overflow-hidden max-h-0 transition-[max-height] duration-200;}.bk-menu__submenu--inline.bk-menu__submenu--open{@apply max-h-[1000px];}.bk-menu__submenu--popup{@apply fixed z-[1000] min-w-[200px] max-w-[280px] max-h-[100vh-16px] overflow-y-auto bg-[var(--menu-bg)] border border-[var(--menu-border)] rounded-xl shadow-[var(--menu-shadow)] p-1 hidden;}.bk-menu__submenu--popup.bk-menu__submenu--open{@apply block;}.bk-menu__submenu--popup-right:before{content:\"\";@apply absolute top-0 left-[-6px] w-1.5 h-full;}.bk-menu__submenu--popup-down:before{content:\"\";@apply absolute top-[-6px] left-0 w-full h-1.5;}@media (max-width: 640px){.bk-menu--horizontal>.bk-menu__list{@apply overflow-x-auto;-webkit-overflow-scrolling:touch}}\n"] }]
|
|
9736
10004
|
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { items: [{
|
|
9737
10005
|
type: Input
|
|
9738
10006
|
}], orientation: [{
|
|
@@ -9762,6 +10030,482 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
9762
10030
|
args: ['window:resize']
|
|
9763
10031
|
}] } });
|
|
9764
10032
|
|
|
10033
|
+
/* =========================================================================
|
|
10034
|
+
Placement maths for bk-popover: turns an anchor rectangle plus a requested
|
|
10035
|
+
placement into viewport coordinates for the panel and its arrow.
|
|
10036
|
+
|
|
10037
|
+
Kept free of the DOM so the rules stay readable and testable — the component
|
|
10038
|
+
measures, this decides.
|
|
10039
|
+
========================================================================= */
|
|
10040
|
+
/** Every placement, in the order a placement picker should show them. */
|
|
10041
|
+
const POPOVER_PLACEMENTS = [
|
|
10042
|
+
'top-left', 'top', 'top-right',
|
|
10043
|
+
'right-top', 'right', 'right-bottom',
|
|
10044
|
+
'bottom-left', 'bottom', 'bottom-right',
|
|
10045
|
+
'left-top', 'left', 'left-bottom'
|
|
10046
|
+
];
|
|
10047
|
+
const OPPOSITE = {
|
|
10048
|
+
top: 'bottom',
|
|
10049
|
+
bottom: 'top',
|
|
10050
|
+
left: 'right',
|
|
10051
|
+
right: 'left'
|
|
10052
|
+
};
|
|
10053
|
+
/**
|
|
10054
|
+
* How close the arrow's centre may get to a panel corner. The panel is rounded,
|
|
10055
|
+
* so an arrow any nearer would grow out of the curve instead of a flat edge.
|
|
10056
|
+
*/
|
|
10057
|
+
const ARROW_CORNER_GAP = 14;
|
|
10058
|
+
/**
|
|
10059
|
+
* The edge each side's alignment words refer to. Top and bottom align across the
|
|
10060
|
+
* x axis, so their words are left/right; left and right align across y, so
|
|
10061
|
+
* theirs are top/bottom.
|
|
10062
|
+
*/
|
|
10063
|
+
const ALIGN_EDGES = {
|
|
10064
|
+
top: { start: 'left', end: 'right' },
|
|
10065
|
+
bottom: { start: 'left', end: 'right' },
|
|
10066
|
+
left: { start: 'top', end: 'bottom' },
|
|
10067
|
+
right: { start: 'top', end: 'bottom' }
|
|
10068
|
+
};
|
|
10069
|
+
/** `top-left` → side `top`, align `start`. A bare side means centred. */
|
|
10070
|
+
function splitPlacement(placement) {
|
|
10071
|
+
const [side, edge] = placement.split('-');
|
|
10072
|
+
if (!edge)
|
|
10073
|
+
return { side, align: 'center' };
|
|
10074
|
+
return { side, align: edge === ALIGN_EDGES[side].start ? 'start' : 'end' };
|
|
10075
|
+
}
|
|
10076
|
+
/**
|
|
10077
|
+
* Inverse of splitPlacement — centred placements lose the suffix. Safe to call
|
|
10078
|
+
* after a flip: flipping only ever swaps a side for its opposite, which shares
|
|
10079
|
+
* the same cross axis, so the alignment word stays meaningful.
|
|
10080
|
+
*/
|
|
10081
|
+
function joinPlacement(side, align) {
|
|
10082
|
+
if (align === 'center')
|
|
10083
|
+
return side;
|
|
10084
|
+
return `${side}-${ALIGN_EDGES[side][align]}`;
|
|
10085
|
+
}
|
|
10086
|
+
function clamp(value, min, max) {
|
|
10087
|
+
// min wins when the range is inverted (panel larger than the viewport), which
|
|
10088
|
+
// keeps the panel's leading edge on screen rather than its trailing one.
|
|
10089
|
+
return Math.max(min, Math.min(value, max));
|
|
10090
|
+
}
|
|
10091
|
+
/** Does the panel clear the viewport edge on this side of the anchor? */
|
|
10092
|
+
function fitsOnSide(side, anchor, panel, { offset, viewportPadding: pad, viewport }) {
|
|
10093
|
+
switch (side) {
|
|
10094
|
+
case 'top':
|
|
10095
|
+
return anchor.top - offset - panel.height >= pad;
|
|
10096
|
+
case 'bottom':
|
|
10097
|
+
return anchor.top + anchor.height + offset + panel.height <= viewport.height - pad;
|
|
10098
|
+
case 'left':
|
|
10099
|
+
return anchor.left - offset - panel.width >= pad;
|
|
10100
|
+
case 'right':
|
|
10101
|
+
return anchor.left + anchor.width + offset + panel.width <= viewport.width - pad;
|
|
10102
|
+
}
|
|
10103
|
+
}
|
|
10104
|
+
/** Leading edge of the panel along the cross axis, before any clamping. */
|
|
10105
|
+
function alignedStart(align, anchorStart, anchorSize, panelSize) {
|
|
10106
|
+
switch (align) {
|
|
10107
|
+
case 'start':
|
|
10108
|
+
return anchorStart;
|
|
10109
|
+
case 'end':
|
|
10110
|
+
return anchorStart + anchorSize - panelSize;
|
|
10111
|
+
case 'center':
|
|
10112
|
+
return anchorStart + anchorSize / 2 - panelSize / 2;
|
|
10113
|
+
}
|
|
10114
|
+
}
|
|
10115
|
+
/**
|
|
10116
|
+
* Places the panel against the anchor, then keeps it on screen in two ways:
|
|
10117
|
+
*
|
|
10118
|
+
* - flip: a panel with no room on the requested side moves to the opposite one,
|
|
10119
|
+
* but only if it actually fits there — flipping into a second bad fit just
|
|
10120
|
+
* trades one clipped edge for another.
|
|
10121
|
+
* - shift: the panel slides along its cross axis to stay inside the viewport.
|
|
10122
|
+
* The arrow is measured against the *anchor*, not the panel, so it keeps
|
|
10123
|
+
* pointing at the trigger however far the panel had to slide.
|
|
10124
|
+
*/
|
|
10125
|
+
function computePopoverPosition(anchor, panel, placement, options) {
|
|
10126
|
+
const { offset, viewportPadding: pad, arrowSize, flip, viewport } = options;
|
|
10127
|
+
let { side, align } = splitPlacement(placement);
|
|
10128
|
+
if (flip && !fitsOnSide(side, anchor, panel, options) && fitsOnSide(OPPOSITE[side], anchor, panel, options)) {
|
|
10129
|
+
side = OPPOSITE[side];
|
|
10130
|
+
}
|
|
10131
|
+
const vertical = side === 'top' || side === 'bottom';
|
|
10132
|
+
let top;
|
|
10133
|
+
let left;
|
|
10134
|
+
if (vertical) {
|
|
10135
|
+
top = side === 'top'
|
|
10136
|
+
? anchor.top - panel.height - offset
|
|
10137
|
+
: anchor.top + anchor.height + offset;
|
|
10138
|
+
left = clamp(alignedStart(align, anchor.left, anchor.width, panel.width), pad, viewport.width - panel.width - pad);
|
|
10139
|
+
}
|
|
10140
|
+
else {
|
|
10141
|
+
left = side === 'left'
|
|
10142
|
+
? anchor.left - panel.width - offset
|
|
10143
|
+
: anchor.left + anchor.width + offset;
|
|
10144
|
+
top = clamp(alignedStart(align, anchor.top, anchor.height, panel.height), pad, viewport.height - panel.height - pad);
|
|
10145
|
+
}
|
|
10146
|
+
const anchorCentre = vertical
|
|
10147
|
+
? anchor.left + anchor.width / 2
|
|
10148
|
+
: anchor.top + anchor.height / 2;
|
|
10149
|
+
const panelStart = vertical ? left : top;
|
|
10150
|
+
const panelSize = vertical ? panel.width : panel.height;
|
|
10151
|
+
const arrowLimit = arrowSize / 2 + ARROW_CORNER_GAP;
|
|
10152
|
+
return {
|
|
10153
|
+
top,
|
|
10154
|
+
left,
|
|
10155
|
+
side,
|
|
10156
|
+
align,
|
|
10157
|
+
placement: joinPlacement(side, align),
|
|
10158
|
+
arrowOffset: clamp(anchorCentre - panelStart, arrowLimit, panelSize - arrowLimit)
|
|
10159
|
+
};
|
|
10160
|
+
}
|
|
10161
|
+
|
|
10162
|
+
/** Edge length of the arrow square. Mirrored by --bk-popover-arrow in popover.css. */
|
|
10163
|
+
const ARROW_SIZE = 10;
|
|
10164
|
+
class BkPopover {
|
|
10165
|
+
/**
|
|
10166
|
+
* One of the 12 placements (`top-left`, `right`, `bottom-right`, …). It is a
|
|
10167
|
+
* preference, not a guarantee: a panel with no room moves to the opposite
|
|
10168
|
+
* side (unless `flip` is off) and slides along the edge to stay on screen.
|
|
10169
|
+
* Read `activePlacement()` for where it actually landed.
|
|
10170
|
+
*/
|
|
10171
|
+
placement = input('bottom', ...(ngDevMode ? [{ debugName: "placement" }] : []));
|
|
10172
|
+
/**
|
|
10173
|
+
* `click` toggles and stays open until dismissed — the right choice for
|
|
10174
|
+
* anything interactive. `hover` opens on the way in and closes on the way
|
|
10175
|
+
* out, with a grace period so the pointer can travel into the panel.
|
|
10176
|
+
*/
|
|
10177
|
+
trigger = input('click', ...(ngDevMode ? [{ debugName: "trigger" }] : []));
|
|
10178
|
+
/** Optional heading. Empty hides the header row entirely. */
|
|
10179
|
+
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
10180
|
+
/** Show the × in the header. Ignored without a `title` to put it in. */
|
|
10181
|
+
closable = input(false, ...(ngDevMode ? [{ debugName: "closable" }] : []));
|
|
10182
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
10183
|
+
showArrow = input(true, ...(ngDevMode ? [{ debugName: "showArrow" }] : []));
|
|
10184
|
+
/** Gap between the trigger and the panel, in px. The arrow spans most of it. */
|
|
10185
|
+
offset = input(8, ...(ngDevMode ? [{ debugName: "offset" }] : []));
|
|
10186
|
+
/** Allow moving to the opposite side when the requested one has no room. */
|
|
10187
|
+
flip = input(true, ...(ngDevMode ? [{ debugName: "flip" }] : []));
|
|
10188
|
+
closeOnClickOutside = input(true, ...(ngDevMode ? [{ debugName: "closeOnClickOutside" }] : []));
|
|
10189
|
+
closeOnEscape = input(true, ...(ngDevMode ? [{ debugName: "closeOnEscape" }] : []));
|
|
10190
|
+
/** Hover only: ms before opening / before closing once the pointer leaves.
|
|
10191
|
+
* The close delay is what makes the panel reachable — drop it to 0 and the
|
|
10192
|
+
* panel disappears as the pointer crosses the gap. */
|
|
10193
|
+
openDelay = input(80, ...(ngDevMode ? [{ debugName: "openDelay" }] : []));
|
|
10194
|
+
closeDelay = input(150, ...(ngDevMode ? [{ debugName: "closeDelay" }] : []));
|
|
10195
|
+
maxWidth = input('280px', ...(ngDevMode ? [{ debugName: "maxWidth" }] : []));
|
|
10196
|
+
panelClass = input('', ...(ngDevMode ? [{ debugName: "panelClass" }] : []));
|
|
10197
|
+
/**
|
|
10198
|
+
* Relocate the panel to <body> while open. `position: fixed` alone resolves
|
|
10199
|
+
* against a transformed ancestor rather than the viewport, so a popover
|
|
10200
|
+
* inside an animated dialog or a transformed card needs this to escape.
|
|
10201
|
+
*/
|
|
10202
|
+
appendToBody = input(false, ...(ngDevMode ? [{ debugName: "appendToBody" }] : []));
|
|
10203
|
+
opened = output();
|
|
10204
|
+
closed = output();
|
|
10205
|
+
openChange = output();
|
|
10206
|
+
anchorRef;
|
|
10207
|
+
panelRef;
|
|
10208
|
+
static activeInstance = null;
|
|
10209
|
+
host = inject(ElementRef);
|
|
10210
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
10211
|
+
/**
|
|
10212
|
+
* Null until the panel has been measured. The template keeps the panel
|
|
10213
|
+
* hidden while it is null: the first frame exists only to measure, and
|
|
10214
|
+
* showing it at 0,0 first would flash it in the corner.
|
|
10215
|
+
*/
|
|
10216
|
+
position = signal(null, ...(ngDevMode ? [{ debugName: "position" }] : []));
|
|
10217
|
+
/** Where the panel actually is, once positioned — may differ from `placement`. */
|
|
10218
|
+
activePlacement = computed(() => this.position()?.placement ?? this.placement(), ...(ngDevMode ? [{ debugName: "activePlacement" }] : []));
|
|
10219
|
+
/** Side the panel sits on. Drives which edge the arrow hangs off (see CSS). */
|
|
10220
|
+
side = computed(() => this.position()?.side ?? splitPlacement(this.placement()).side, ...(ngDevMode ? [{ debugName: "side" }] : []));
|
|
10221
|
+
openTimer = null;
|
|
10222
|
+
closeTimer = null;
|
|
10223
|
+
pointerInPanel = false;
|
|
10224
|
+
resizeObserver;
|
|
10225
|
+
// Panel's home in the DOM, so appendToBody can put it back before Angular's
|
|
10226
|
+
// @if removes it.
|
|
10227
|
+
originalPanelParent = null;
|
|
10228
|
+
originalPanelAnchor = null;
|
|
10229
|
+
panelInBody = false;
|
|
10230
|
+
ngAfterViewInit() {
|
|
10231
|
+
// Capture phase catches scrolling inside nested overflow containers, which
|
|
10232
|
+
// a window:scroll listener would miss entirely.
|
|
10233
|
+
window.addEventListener('scroll', this.reposition, true);
|
|
10234
|
+
window.addEventListener('resize', this.reposition);
|
|
10235
|
+
// Content can change size while open (async data, an expanding section),
|
|
10236
|
+
// which moves every edge the panel is aligned against.
|
|
10237
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
10238
|
+
this.resizeObserver = new ResizeObserver(() => this.measure());
|
|
10239
|
+
}
|
|
10240
|
+
}
|
|
10241
|
+
ngOnDestroy() {
|
|
10242
|
+
this.clearTimers();
|
|
10243
|
+
this.resizeObserver?.disconnect();
|
|
10244
|
+
document.removeEventListener('click', this.onDocumentClick);
|
|
10245
|
+
window.removeEventListener('scroll', this.reposition, true);
|
|
10246
|
+
window.removeEventListener('resize', this.reposition);
|
|
10247
|
+
// Don't leave a relocated panel orphaned in <body> if we're torn down open.
|
|
10248
|
+
if (this.panelInBody) {
|
|
10249
|
+
this.panelRef?.nativeElement.remove();
|
|
10250
|
+
this.panelInBody = false;
|
|
10251
|
+
}
|
|
10252
|
+
if (BkPopover.activeInstance === this)
|
|
10253
|
+
BkPopover.activeInstance = null;
|
|
10254
|
+
}
|
|
10255
|
+
// --- Public API ---
|
|
10256
|
+
open() {
|
|
10257
|
+
if (this.isOpen() || this.disabled())
|
|
10258
|
+
return;
|
|
10259
|
+
// Two popovers open at once is nearly always an accident of a missed close.
|
|
10260
|
+
if (BkPopover.activeInstance && BkPopover.activeInstance !== this) {
|
|
10261
|
+
BkPopover.activeInstance.close();
|
|
10262
|
+
}
|
|
10263
|
+
BkPopover.activeInstance = this;
|
|
10264
|
+
this.clearTimers();
|
|
10265
|
+
this.position.set(null);
|
|
10266
|
+
this.isOpen.set(true);
|
|
10267
|
+
this.opened.emit();
|
|
10268
|
+
this.openChange.emit(true);
|
|
10269
|
+
// The panel doesn't exist until Angular renders it, and it can't be
|
|
10270
|
+
// measured before it does — so position on the next tick.
|
|
10271
|
+
setTimeout(() => {
|
|
10272
|
+
if (!this.isOpen())
|
|
10273
|
+
return;
|
|
10274
|
+
if (this.appendToBody())
|
|
10275
|
+
this.movePanelToBody();
|
|
10276
|
+
this.measure();
|
|
10277
|
+
if (this.panelRef)
|
|
10278
|
+
this.resizeObserver?.observe(this.panelRef.nativeElement);
|
|
10279
|
+
// Attached here, not on the host, so the very click that opened the panel
|
|
10280
|
+
// has finished bubbling first — otherwise a popover opened by anything
|
|
10281
|
+
// outside its own trigger (a toolbar button calling open()) would be shut
|
|
10282
|
+
// again by its own opening click.
|
|
10283
|
+
document.addEventListener('click', this.onDocumentClick);
|
|
10284
|
+
});
|
|
10285
|
+
}
|
|
10286
|
+
close() {
|
|
10287
|
+
if (!this.isOpen())
|
|
10288
|
+
return;
|
|
10289
|
+
this.clearTimers();
|
|
10290
|
+
this.resizeObserver?.disconnect();
|
|
10291
|
+
document.removeEventListener('click', this.onDocumentClick);
|
|
10292
|
+
this.restorePanel();
|
|
10293
|
+
this.isOpen.set(false);
|
|
10294
|
+
this.position.set(null);
|
|
10295
|
+
this.pointerInPanel = false;
|
|
10296
|
+
this.closed.emit();
|
|
10297
|
+
this.openChange.emit(false);
|
|
10298
|
+
if (BkPopover.activeInstance === this)
|
|
10299
|
+
BkPopover.activeInstance = null;
|
|
10300
|
+
}
|
|
10301
|
+
toggle() {
|
|
10302
|
+
this.isOpen() ? this.close() : this.open();
|
|
10303
|
+
}
|
|
10304
|
+
// --- Trigger handling ---
|
|
10305
|
+
onAnchorClick() {
|
|
10306
|
+
if (this.trigger() !== 'click' || this.disabled())
|
|
10307
|
+
return;
|
|
10308
|
+
this.toggle();
|
|
10309
|
+
}
|
|
10310
|
+
onAnchorEnter() {
|
|
10311
|
+
if (this.trigger() !== 'hover' || this.disabled())
|
|
10312
|
+
return;
|
|
10313
|
+
this.cancelClose();
|
|
10314
|
+
this.openTimer = setTimeout(() => this.open(), this.openDelay());
|
|
10315
|
+
}
|
|
10316
|
+
onAnchorLeave() {
|
|
10317
|
+
if (this.trigger() !== 'hover')
|
|
10318
|
+
return;
|
|
10319
|
+
this.cancelOpen();
|
|
10320
|
+
this.scheduleClose();
|
|
10321
|
+
}
|
|
10322
|
+
onPanelEnter() {
|
|
10323
|
+
if (this.trigger() !== 'hover')
|
|
10324
|
+
return;
|
|
10325
|
+
this.pointerInPanel = true;
|
|
10326
|
+
this.cancelClose();
|
|
10327
|
+
}
|
|
10328
|
+
onPanelLeave() {
|
|
10329
|
+
if (this.trigger() !== 'hover')
|
|
10330
|
+
return;
|
|
10331
|
+
this.pointerInPanel = false;
|
|
10332
|
+
this.scheduleClose();
|
|
10333
|
+
}
|
|
10334
|
+
/** Only attached while open — see open(). Arrow fn so it can be removed. */
|
|
10335
|
+
onDocumentClick = (event) => {
|
|
10336
|
+
if (this.trigger() !== 'click' || !this.closeOnClickOutside())
|
|
10337
|
+
return;
|
|
10338
|
+
const target = event.target;
|
|
10339
|
+
if (this.host.nativeElement.contains(target))
|
|
10340
|
+
return;
|
|
10341
|
+
// appendToBody moves the panel out of the host, so clicking inside it would
|
|
10342
|
+
// otherwise read as an outside click.
|
|
10343
|
+
if (this.panelRef?.nativeElement.contains(target))
|
|
10344
|
+
return;
|
|
10345
|
+
this.close();
|
|
10346
|
+
};
|
|
10347
|
+
onEscape() {
|
|
10348
|
+
if (this.isOpen() && this.closeOnEscape())
|
|
10349
|
+
this.close();
|
|
10350
|
+
}
|
|
10351
|
+
// --- Positioning ---
|
|
10352
|
+
reposition = () => {
|
|
10353
|
+
if (this.isOpen())
|
|
10354
|
+
this.measure();
|
|
10355
|
+
};
|
|
10356
|
+
/** Measures the anchor and panel, then hands the maths to the utility. */
|
|
10357
|
+
measure() {
|
|
10358
|
+
const anchor = this.anchorRef?.nativeElement;
|
|
10359
|
+
const panel = this.panelRef?.nativeElement;
|
|
10360
|
+
if (!anchor || !panel)
|
|
10361
|
+
return;
|
|
10362
|
+
const anchorRect = anchor.getBoundingClientRect();
|
|
10363
|
+
this.position.set(computePopoverPosition({
|
|
10364
|
+
top: anchorRect.top,
|
|
10365
|
+
left: anchorRect.left,
|
|
10366
|
+
width: anchorRect.width,
|
|
10367
|
+
height: anchorRect.height
|
|
10368
|
+
}, { width: panel.offsetWidth, height: panel.offsetHeight }, this.placement(), {
|
|
10369
|
+
offset: this.offset(),
|
|
10370
|
+
viewportPadding: 8,
|
|
10371
|
+
arrowSize: ARROW_SIZE,
|
|
10372
|
+
flip: this.flip(),
|
|
10373
|
+
viewport: { width: window.innerWidth, height: window.innerHeight }
|
|
10374
|
+
}));
|
|
10375
|
+
}
|
|
10376
|
+
/** Arrow offset along the panel's cross axis — x on top/bottom, y on left/right. */
|
|
10377
|
+
arrowLeft = computed(() => {
|
|
10378
|
+
const pos = this.position();
|
|
10379
|
+
if (!pos)
|
|
10380
|
+
return null;
|
|
10381
|
+
return pos.side === 'top' || pos.side === 'bottom' ? pos.arrowOffset : null;
|
|
10382
|
+
}, ...(ngDevMode ? [{ debugName: "arrowLeft" }] : []));
|
|
10383
|
+
arrowTop = computed(() => {
|
|
10384
|
+
const pos = this.position();
|
|
10385
|
+
if (!pos)
|
|
10386
|
+
return null;
|
|
10387
|
+
return pos.side === 'left' || pos.side === 'right' ? pos.arrowOffset : null;
|
|
10388
|
+
}, ...(ngDevMode ? [{ debugName: "arrowTop" }] : []));
|
|
10389
|
+
movePanelToBody() {
|
|
10390
|
+
const panel = this.panelRef?.nativeElement;
|
|
10391
|
+
if (!panel || this.panelInBody)
|
|
10392
|
+
return;
|
|
10393
|
+
this.originalPanelParent = panel.parentNode;
|
|
10394
|
+
this.originalPanelAnchor = panel.nextSibling;
|
|
10395
|
+
document.body.appendChild(panel);
|
|
10396
|
+
this.panelInBody = true;
|
|
10397
|
+
}
|
|
10398
|
+
restorePanel() {
|
|
10399
|
+
const panel = this.panelRef?.nativeElement;
|
|
10400
|
+
if (!panel || !this.panelInBody)
|
|
10401
|
+
return;
|
|
10402
|
+
this.originalPanelParent?.insertBefore(panel, this.originalPanelAnchor);
|
|
10403
|
+
this.panelInBody = false;
|
|
10404
|
+
this.originalPanelParent = null;
|
|
10405
|
+
this.originalPanelAnchor = null;
|
|
10406
|
+
}
|
|
10407
|
+
// --- Timers ---
|
|
10408
|
+
scheduleClose() {
|
|
10409
|
+
this.cancelClose();
|
|
10410
|
+
this.closeTimer = setTimeout(() => {
|
|
10411
|
+
if (!this.pointerInPanel)
|
|
10412
|
+
this.close();
|
|
10413
|
+
}, this.closeDelay());
|
|
10414
|
+
}
|
|
10415
|
+
cancelOpen() {
|
|
10416
|
+
if (this.openTimer) {
|
|
10417
|
+
clearTimeout(this.openTimer);
|
|
10418
|
+
this.openTimer = null;
|
|
10419
|
+
}
|
|
10420
|
+
}
|
|
10421
|
+
cancelClose() {
|
|
10422
|
+
if (this.closeTimer) {
|
|
10423
|
+
clearTimeout(this.closeTimer);
|
|
10424
|
+
this.closeTimer = null;
|
|
10425
|
+
}
|
|
10426
|
+
}
|
|
10427
|
+
clearTimers() {
|
|
10428
|
+
this.cancelOpen();
|
|
10429
|
+
this.cancelClose();
|
|
10430
|
+
}
|
|
10431
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkPopover, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10432
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkPopover, isStandalone: true, selector: "bk-popover", inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showArrow: { classPropertyName: "showArrow", publicName: "showArrow", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, flip: { classPropertyName: "flip", publicName: "flip", isSignal: true, isRequired: false, transformFunction: null }, closeOnClickOutside: { classPropertyName: "closeOnClickOutside", publicName: "closeOnClickOutside", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, openDelay: { classPropertyName: "openDelay", publicName: "openDelay", isSignal: true, isRequired: false, transformFunction: null }, closeDelay: { classPropertyName: "closeDelay", publicName: "closeDelay", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, appendToBody: { classPropertyName: "appendToBody", publicName: "appendToBody", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed", openChange: "openChange" }, host: { listeners: { "document:keydown.escape": "onEscape()" }, properties: { "attr.title": "null" } }, viewQueries: [{ propertyName: "anchorRef", first: true, predicate: ["anchor"], descendants: true }, { propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true }], ngImport: i0, template: "<!-- The anchor wraps the projected trigger so the popover has an element to\r\n measure and to listen on, whatever the consumer passes in. -->\r\n<span\r\n #anchor\r\n class=\"bk-popover-anchor\"\r\n (click)=\"onAnchorClick()\"\r\n (mouseenter)=\"onAnchorEnter()\"\r\n (mouseleave)=\"onAnchorLeave()\"\r\n>\r\n <ng-content select=\"[bkPopoverTrigger]\"></ng-content>\r\n</span>\r\n\r\n@if (isOpen()) {\r\n <!-- Hidden until position() lands: the first frame exists only so the panel\r\n can be measured, and painting it at 0,0 first flashes it in the corner. -->\r\n <div\r\n #panel\r\n class=\"bk-popover-panel\"\r\n [ngClass]=\"panelClass()\"\r\n role=\"dialog\"\r\n [attr.data-side]=\"side()\"\r\n [style.top.px]=\"position()?.top\"\r\n [style.left.px]=\"position()?.left\"\r\n [style.maxWidth]=\"maxWidth()\"\r\n [class.bk-popover-ready]=\"!!position()\"\r\n (mouseenter)=\"onPanelEnter()\"\r\n (mouseleave)=\"onPanelLeave()\"\r\n >\r\n @if (showArrow()) {\r\n <!-- A rotated square, not a border triangle: it inherits the panel's\r\n background and border, so the tip matches the panel on every side.\r\n Sits above the panel's own border, hiding the segment it crosses. -->\r\n <span\r\n class=\"bk-popover-arrow\"\r\n [style.left.px]=\"arrowLeft()\"\r\n [style.top.px]=\"arrowTop()\"\r\n ></span>\r\n }\r\n\r\n @if (title()) {\r\n <div class=\"bk-popover-header\">\r\n <span class=\"bk-popover-title\">{{ title() }}</span>\r\n @if (closable()) {\r\n <button type=\"button\" class=\"bk-popover-close\" aria-label=\"Close\" (click)=\"close()\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"bk-popover-body\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n}\r\n", styles: [":host{@apply inline-flex;}.bk-popover-anchor{@apply inline-flex;}.bk-popover-panel{@apply fixed z-[10000] bg-white border border-[#E3E3E7] rounded-lg p-3 cursor-default;box-shadow:0 12px 24px -6px #1018281f,0 4px 8px -4px #1018280f;visibility:hidden;opacity:0}.bk-popover-panel.bk-popover-ready{visibility:visible;opacity:1;transition:opacity .12s ease-out}.bk-popover-arrow{@apply absolute block w-2.5 h-2.5 bg-white border border-[#E3E3E7];}.bk-popover-panel[data-side=top] .bk-popover-arrow{bottom:-5px;border-top:none;border-left:none;transform:translate(-50%) rotate(45deg)}.bk-popover-panel[data-side=bottom] .bk-popover-arrow{top:-5px;border-bottom:none;border-right:none;transform:translate(-50%) rotate(45deg)}.bk-popover-panel[data-side=left] .bk-popover-arrow{right:-5px;border-bottom:none;border-left:none;transform:translateY(-50%) rotate(45deg)}.bk-popover-panel[data-side=right] .bk-popover-arrow{left:-5px;border-top:none;border-right:none;transform:translateY(-50%) rotate(45deg)}.bk-popover-header{@apply flex items-start justify-between gap-3 mb-1;}.bk-popover-title{@apply text-sm font-semibold text-[#141414];}.bk-popover-close{@apply shrink-0 text-gray-400 hover:text-[#141414] cursor-pointer -me-1 -mt-0.5;}.bk-popover-body{@apply text-sm font-normal text-[#6B7080];}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
10433
|
+
}
|
|
10434
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkPopover, decorators: [{
|
|
10435
|
+
type: Component,
|
|
10436
|
+
args: [{ selector: 'bk-popover', standalone: true, imports: [CommonModule], host: {
|
|
10437
|
+
// A static `title="…"` lands on the input *and* stays on the host as a real
|
|
10438
|
+
// HTML attribute, which the browser would render as its own native tooltip
|
|
10439
|
+
// over the trigger. Stripping it here means the input can keep the obvious
|
|
10440
|
+
// name without consumers having to remember to bind it.
|
|
10441
|
+
'[attr.title]': 'null'
|
|
10442
|
+
}, template: "<!-- The anchor wraps the projected trigger so the popover has an element to\r\n measure and to listen on, whatever the consumer passes in. -->\r\n<span\r\n #anchor\r\n class=\"bk-popover-anchor\"\r\n (click)=\"onAnchorClick()\"\r\n (mouseenter)=\"onAnchorEnter()\"\r\n (mouseleave)=\"onAnchorLeave()\"\r\n>\r\n <ng-content select=\"[bkPopoverTrigger]\"></ng-content>\r\n</span>\r\n\r\n@if (isOpen()) {\r\n <!-- Hidden until position() lands: the first frame exists only so the panel\r\n can be measured, and painting it at 0,0 first flashes it in the corner. -->\r\n <div\r\n #panel\r\n class=\"bk-popover-panel\"\r\n [ngClass]=\"panelClass()\"\r\n role=\"dialog\"\r\n [attr.data-side]=\"side()\"\r\n [style.top.px]=\"position()?.top\"\r\n [style.left.px]=\"position()?.left\"\r\n [style.maxWidth]=\"maxWidth()\"\r\n [class.bk-popover-ready]=\"!!position()\"\r\n (mouseenter)=\"onPanelEnter()\"\r\n (mouseleave)=\"onPanelLeave()\"\r\n >\r\n @if (showArrow()) {\r\n <!-- A rotated square, not a border triangle: it inherits the panel's\r\n background and border, so the tip matches the panel on every side.\r\n Sits above the panel's own border, hiding the segment it crosses. -->\r\n <span\r\n class=\"bk-popover-arrow\"\r\n [style.left.px]=\"arrowLeft()\"\r\n [style.top.px]=\"arrowTop()\"\r\n ></span>\r\n }\r\n\r\n @if (title()) {\r\n <div class=\"bk-popover-header\">\r\n <span class=\"bk-popover-title\">{{ title() }}</span>\r\n @if (closable()) {\r\n <button type=\"button\" class=\"bk-popover-close\" aria-label=\"Close\" (click)=\"close()\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"bk-popover-body\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n}\r\n", styles: [":host{@apply inline-flex;}.bk-popover-anchor{@apply inline-flex;}.bk-popover-panel{@apply fixed z-[10000] bg-white border border-[#E3E3E7] rounded-lg p-3 cursor-default;box-shadow:0 12px 24px -6px #1018281f,0 4px 8px -4px #1018280f;visibility:hidden;opacity:0}.bk-popover-panel.bk-popover-ready{visibility:visible;opacity:1;transition:opacity .12s ease-out}.bk-popover-arrow{@apply absolute block w-2.5 h-2.5 bg-white border border-[#E3E3E7];}.bk-popover-panel[data-side=top] .bk-popover-arrow{bottom:-5px;border-top:none;border-left:none;transform:translate(-50%) rotate(45deg)}.bk-popover-panel[data-side=bottom] .bk-popover-arrow{top:-5px;border-bottom:none;border-right:none;transform:translate(-50%) rotate(45deg)}.bk-popover-panel[data-side=left] .bk-popover-arrow{right:-5px;border-bottom:none;border-left:none;transform:translateY(-50%) rotate(45deg)}.bk-popover-panel[data-side=right] .bk-popover-arrow{left:-5px;border-top:none;border-right:none;transform:translateY(-50%) rotate(45deg)}.bk-popover-header{@apply flex items-start justify-between gap-3 mb-1;}.bk-popover-title{@apply text-sm font-semibold text-[#141414];}.bk-popover-close{@apply shrink-0 text-gray-400 hover:text-[#141414] cursor-pointer -me-1 -mt-0.5;}.bk-popover-body{@apply text-sm font-normal text-[#6B7080];}\n"] }]
|
|
10443
|
+
}], propDecorators: { placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showArrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "showArrow", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], flip: [{ type: i0.Input, args: [{ isSignal: true, alias: "flip", required: false }] }], closeOnClickOutside: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClickOutside", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], openDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "openDelay", required: false }] }], closeDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeDelay", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], appendToBody: [{ type: i0.Input, args: [{ isSignal: true, alias: "appendToBody", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], openChange: [{ type: i0.Output, args: ["openChange"] }], anchorRef: [{
|
|
10444
|
+
type: ViewChild,
|
|
10445
|
+
args: ['anchor']
|
|
10446
|
+
}], panelRef: [{
|
|
10447
|
+
type: ViewChild,
|
|
10448
|
+
args: ['panel']
|
|
10449
|
+
}], onEscape: [{
|
|
10450
|
+
type: HostListener,
|
|
10451
|
+
args: ['document:keydown.escape']
|
|
10452
|
+
}] } });
|
|
10453
|
+
|
|
10454
|
+
/**
|
|
10455
|
+
* A stacked ("avatar list") group. Renders a set of overlapping `bk-avatar`s and
|
|
10456
|
+
* collapses any beyond `max` into a `+N` bubble whose tooltip lists the hidden
|
|
10457
|
+
* names. Uses bk-avatar for every slot, so image/initials/icon fallback, sizing
|
|
10458
|
+
* and status dots all come for free.
|
|
10459
|
+
*/
|
|
10460
|
+
class BkAvatarGroup {
|
|
10461
|
+
/** The people to stack. */
|
|
10462
|
+
avatars = [];
|
|
10463
|
+
/** Shared size for every avatar in the group. */
|
|
10464
|
+
size = 'md';
|
|
10465
|
+
/** Max avatars shown before collapsing the rest into a +N bubble. */
|
|
10466
|
+
max = 3;
|
|
10467
|
+
/** Default variant for items that don't set their own. */
|
|
10468
|
+
variant = 'gray';
|
|
10469
|
+
/** Show the +N overflow bubble (otherwise extra avatars are just hidden). */
|
|
10470
|
+
showOverflow = true;
|
|
10471
|
+
get visibleAvatars() {
|
|
10472
|
+
return this.avatars.slice(0, this.max);
|
|
10473
|
+
}
|
|
10474
|
+
get overflowCount() {
|
|
10475
|
+
return Math.max(0, this.avatars.length - this.max);
|
|
10476
|
+
}
|
|
10477
|
+
get overflowLabel() {
|
|
10478
|
+
return `+${this.overflowCount}`;
|
|
10479
|
+
}
|
|
10480
|
+
/** Names of the hidden avatars, for the +N tooltip. */
|
|
10481
|
+
get overflowTooltip() {
|
|
10482
|
+
return this.avatars
|
|
10483
|
+
.slice(this.max)
|
|
10484
|
+
.map(a => a.name?.trim())
|
|
10485
|
+
.filter((n) => !!n)
|
|
10486
|
+
.join(', ');
|
|
10487
|
+
}
|
|
10488
|
+
trackByIndex(index) {
|
|
10489
|
+
return index;
|
|
10490
|
+
}
|
|
10491
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkAvatarGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10492
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkAvatarGroup, isStandalone: true, selector: "bk-avatar-group", inputs: { avatars: "avatars", size: "size", max: "max", variant: "variant", showOverflow: "showOverflow" }, ngImport: i0, template: "<div class=\"bk-avatar-group\" [ngClass]=\"size\">\r\n @for (item of visibleAvatars; track trackByIndex($index)) {\r\n <span class=\"bk-avatar-group__item\">\r\n <bk-avatar\r\n [src]=\"item.src ?? null\"\r\n [name]=\"item.name ?? ''\"\r\n [initialsOverride]=\"item.initialsOverride ?? ''\"\r\n [alt]=\"item.alt ?? 'Avatar'\"\r\n [tooltipContent]=\"item.tooltipContent ?? null\"\r\n [bgColor]=\"item.bgColor ?? null\"\r\n [textColor]=\"item.textColor ?? null\"\r\n [size]=\"size\"\r\n [variant]=\"item.variant ?? variant\"\r\n [dot]=\"item.dot ?? 'none'\"\r\n [dotPosition]=\"item.dotPosition ?? 'bottom-right'\"\r\n ></bk-avatar>\r\n </span>\r\n }\r\n\r\n @if (showOverflow && overflowCount > 0) {\r\n <span class=\"bk-avatar-group__item bk-avatar-group__item--overflow\">\r\n <bk-avatar\r\n [name]=\"overflowLabel\"\r\n [initialsOverride]=\"overflowLabel\"\r\n [tooltipContent]=\"overflowTooltip\"\r\n [size]=\"size\"\r\n variant=\"gray\"\r\n bgColor=\"#F3F4F6\"\r\n textColor=\"#4A5565\"\r\n ></bk-avatar>\r\n </span>\r\n }\r\n</div>\r\n", styles: [".bk-avatar-group{@apply inline-flex items-center;}.bk-avatar-group__item{@apply relative inline-flex rounded-full transition-transform duration-150;box-shadow:0 0 0 2px #fff}.bk-avatar-group__item:hover{@apply z-10;}.bk-avatar-group__item--overflow{@apply cursor-pointer;}.bk-avatar-group.xsm .bk-avatar-group__item:not(:first-child){margin-left:-8px}.bk-avatar-group.sm .bk-avatar-group__item:not(:first-child){margin-left:-10px}.bk-avatar-group.md .bk-avatar-group__item:not(:first-child){margin-left:-12px}.bk-avatar-group.lg .bk-avatar-group__item:not(:first-child){margin-left:-16px}.bk-avatar-group.xl .bk-avatar-group__item:not(:first-child){margin-left:-18px}.bk-avatar-group.xxl .bk-avatar-group__item:not(:first-child){margin-left:-20px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: BkAvatar, selector: "bk-avatar", inputs: ["src", "alt", "name", "initialsOverride", "tooltipContent", "bgColor", "textColor", "size", "variant", "fallback", "dot", "dotPosition"], outputs: ["imageLoadError"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
10493
|
+
}
|
|
10494
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkAvatarGroup, decorators: [{
|
|
10495
|
+
type: Component,
|
|
10496
|
+
args: [{ selector: 'bk-avatar-group', standalone: true, imports: [CommonModule, BkAvatar], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"bk-avatar-group\" [ngClass]=\"size\">\r\n @for (item of visibleAvatars; track trackByIndex($index)) {\r\n <span class=\"bk-avatar-group__item\">\r\n <bk-avatar\r\n [src]=\"item.src ?? null\"\r\n [name]=\"item.name ?? ''\"\r\n [initialsOverride]=\"item.initialsOverride ?? ''\"\r\n [alt]=\"item.alt ?? 'Avatar'\"\r\n [tooltipContent]=\"item.tooltipContent ?? null\"\r\n [bgColor]=\"item.bgColor ?? null\"\r\n [textColor]=\"item.textColor ?? null\"\r\n [size]=\"size\"\r\n [variant]=\"item.variant ?? variant\"\r\n [dot]=\"item.dot ?? 'none'\"\r\n [dotPosition]=\"item.dotPosition ?? 'bottom-right'\"\r\n ></bk-avatar>\r\n </span>\r\n }\r\n\r\n @if (showOverflow && overflowCount > 0) {\r\n <span class=\"bk-avatar-group__item bk-avatar-group__item--overflow\">\r\n <bk-avatar\r\n [name]=\"overflowLabel\"\r\n [initialsOverride]=\"overflowLabel\"\r\n [tooltipContent]=\"overflowTooltip\"\r\n [size]=\"size\"\r\n variant=\"gray\"\r\n bgColor=\"#F3F4F6\"\r\n textColor=\"#4A5565\"\r\n ></bk-avatar>\r\n </span>\r\n }\r\n</div>\r\n", styles: [".bk-avatar-group{@apply inline-flex items-center;}.bk-avatar-group__item{@apply relative inline-flex rounded-full transition-transform duration-150;box-shadow:0 0 0 2px #fff}.bk-avatar-group__item:hover{@apply z-10;}.bk-avatar-group__item--overflow{@apply cursor-pointer;}.bk-avatar-group.xsm .bk-avatar-group__item:not(:first-child){margin-left:-8px}.bk-avatar-group.sm .bk-avatar-group__item:not(:first-child){margin-left:-10px}.bk-avatar-group.md .bk-avatar-group__item:not(:first-child){margin-left:-12px}.bk-avatar-group.lg .bk-avatar-group__item:not(:first-child){margin-left:-16px}.bk-avatar-group.xl .bk-avatar-group__item:not(:first-child){margin-left:-18px}.bk-avatar-group.xxl .bk-avatar-group__item:not(:first-child){margin-left:-20px}\n"] }]
|
|
10497
|
+
}], propDecorators: { avatars: [{
|
|
10498
|
+
type: Input
|
|
10499
|
+
}], size: [{
|
|
10500
|
+
type: Input
|
|
10501
|
+
}], max: [{
|
|
10502
|
+
type: Input
|
|
10503
|
+
}], variant: [{
|
|
10504
|
+
type: Input
|
|
10505
|
+
}], showOverflow: [{
|
|
10506
|
+
type: Input
|
|
10507
|
+
}] } });
|
|
10508
|
+
|
|
9765
10509
|
/*
|
|
9766
10510
|
* Public API Surface of brickclay-lib
|
|
9767
10511
|
*/
|
|
@@ -9771,5 +10515,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
9771
10515
|
* Generated bundle index. Do not edit.
|
|
9772
10516
|
*/
|
|
9773
10517
|
|
|
9774
|
-
export { BKTooltipDirective, BK_DEFAULT_DIALOG_CONFIG, BK_DIALOG_DATA, BK_DIALOG_GLOBAL_CONFIG, BkAvatar, BkAvatarUploader, BkBadge, BkButton, BkButtonGroup, BkCalendarManagerService, BkCheckbox, BkColumnFilterService, BkColumnSelect, BkCustomCalendar, BkDialogActions, BkDialogClose, BkDialogContent, BkDialogModule, BkDialogRef, BkDialogService, BkDialogTitle, BkDropdown, BkFileCard, BkFilePicker, BkGrid, BkHierarchicalSelect, BkIconButton, BkInput, BkInputChips, BkLoader, BkMenu, BkPagination, BkPill, BkRadioButton, BkScheduledDatePicker, BkSelect, BkSpinner, BkTabs, BkTextarea, BkTimePicker, BkToastr, BkToastrService, BkToggle, BkValidator, BrickclayIcons, BrickclayLib, CalendarModule, CalendarSelection, ColumnFilterOption, getDialogBackdropAnimation, getDialogPanelAnimation };
|
|
10518
|
+
export { BKTooltipDirective, BK_DEFAULT_DIALOG_CONFIG, BK_DIALOG_DATA, BK_DIALOG_GLOBAL_CONFIG, BkAvatar, BkAvatarGroup, BkAvatarUploader, BkBadge, BkButton, BkButtonGroup, BkCalendarManagerService, BkCheckbox, BkColumnFilterService, BkColumnSelect, BkCustomCalendar, BkDialogActions, BkDialogClose, BkDialogContent, BkDialogModule, BkDialogRef, BkDialogService, BkDialogTitle, BkDropdown, BkFileCard, BkFilePicker, BkGrid, BkHierarchicalSelect, BkIconButton, BkInput, BkInputChips, BkLoader, BkMenu, BkPagination, BkPill, BkPopover, BkRadioButton, BkScheduledDatePicker, BkSelect, BkSpinner, BkTabs, BkTextarea, BkTimePicker, BkToastr, BkToastrService, BkToggle, BkValidator, BrickclayIcons, BrickclayLib, CalendarModule, CalendarSelection, ColumnFilterOption, NEUTRAL_APPEARANCE, POPOVER_PLACEMENTS, computePopoverPosition, deriveAppearance, getDialogBackdropAnimation, getDialogPanelAnimation, joinPlacement, parseColor, splitPlacement };
|
|
9775
10519
|
//# sourceMappingURL=brickclay-org-ui.mjs.map
|