@bravobit/bb-foundation 0.51.7 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/elements/lib/elements.interfaces.d.ts +1 -0
- package/elements/lib/file-picker/file-picker.component.d.ts +3 -1
- package/elements/lib/multi-file-control/multi-file-control.component.d.ts +6 -6
- package/fesm2022/bravobit-bb-foundation-elements.mjs +34 -22
- package/fesm2022/bravobit-bb-foundation-elements.mjs.map +1 -1
- package/localize/lib/transforms/interpolate.transform.d.ts +1 -1
- package/localize/lib/transforms/plural.transform.d.ts +1 -1
- package/localize/lib/transforms/reference.transform.d.ts +1 -1
- package/package.json +8 -8
|
@@ -3,12 +3,13 @@ import { ControlValueAccessor, FormControl } from '@angular/forms';
|
|
|
3
3
|
import { BehaviorSubject } from 'rxjs';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
export declare class BbFilePicker implements ControlValueAccessor {
|
|
6
|
+
private readonly _config?;
|
|
6
7
|
readonly labelId: string;
|
|
7
8
|
fileInput: ElementRef<HTMLInputElement>;
|
|
8
9
|
extraTemplate: TemplateRef<any>;
|
|
9
10
|
label: string | TemplateRef<any> | null;
|
|
10
11
|
hint: string | TemplateRef<any> | null;
|
|
11
|
-
accept: string
|
|
12
|
+
accept: string;
|
|
12
13
|
showImages: boolean;
|
|
13
14
|
grouped: boolean;
|
|
14
15
|
required: boolean;
|
|
@@ -39,6 +40,7 @@ export declare class BbFilePicker implements ControlValueAccessor {
|
|
|
39
40
|
};
|
|
40
41
|
saveFile(files: File[]): void;
|
|
41
42
|
private getFilesFromEvent;
|
|
43
|
+
private getAcceptString;
|
|
42
44
|
static ɵfac: i0.ɵɵFactoryDeclaration<BbFilePicker, never>;
|
|
43
45
|
static ɵcmp: i0.ɵɵComponentDeclaration<BbFilePicker, "bb-file-picker", never, { "label": { "alias": "label"; "required": false; }; "hint": { "alias": "hint"; "required": false; }; "accept": { "alias": "accept"; "required": false; }; "showImages": { "alias": "showImages"; "required": false; }; "grouped": { "alias": "grouped"; "required": false; }; "required": { "alias": "required"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "hideErrors": { "alias": "hideErrors"; "required": false; }; "value": { "alias": "value"; "required": false; }; }, { "valueChange": "valueChange"; }, ["extraTemplate"], never, true, never>;
|
|
44
46
|
static ngAcceptInputType_grouped: unknown;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ElementRef, EventEmitter, TemplateRef } from '@angular/core';
|
|
2
2
|
import { ControlValueAccessor, FormControl } from '@angular/forms';
|
|
3
|
-
import { Files } from '@bravobit/bb-foundation';
|
|
4
3
|
import * as i0 from "@angular/core";
|
|
5
4
|
export declare class BbMultiFileControl implements ControlValueAccessor {
|
|
6
|
-
private _files;
|
|
7
|
-
private _changeDetectorRef;
|
|
5
|
+
private readonly _files;
|
|
6
|
+
private readonly _changeDetectorRef;
|
|
7
|
+
private readonly _config?;
|
|
8
8
|
readonly labelId: string;
|
|
9
9
|
fileInput: ElementRef<HTMLInputElement>;
|
|
10
10
|
label: string | TemplateRef<any> | null;
|
|
11
11
|
hint: string | TemplateRef<any> | null;
|
|
12
|
-
accept: string
|
|
12
|
+
accept: string;
|
|
13
13
|
grouped: boolean;
|
|
14
14
|
required: boolean;
|
|
15
15
|
disabled: boolean;
|
|
@@ -28,7 +28,6 @@ export declare class BbMultiFileControl implements ControlValueAccessor {
|
|
|
28
28
|
error: boolean;
|
|
29
29
|
onTouchedCallback: () => void;
|
|
30
30
|
onChangeCallback: (_: File[] | null) => void;
|
|
31
|
-
constructor(_files: Files, _changeDetectorRef: ChangeDetectorRef);
|
|
32
31
|
get showList(): boolean;
|
|
33
32
|
downloadFile(file: File): void;
|
|
34
33
|
openFileDialog(): void;
|
|
@@ -47,6 +46,7 @@ export declare class BbMultiFileControl implements ControlValueAccessor {
|
|
|
47
46
|
};
|
|
48
47
|
addFiles(files: File[]): void;
|
|
49
48
|
private isFileLike;
|
|
49
|
+
private getAcceptString;
|
|
50
50
|
static ɵfac: i0.ɵɵFactoryDeclaration<BbMultiFileControl, never>;
|
|
51
51
|
static ɵcmp: i0.ɵɵComponentDeclaration<BbMultiFileControl, "bb-multi-file-control", never, { "label": { "alias": "label"; "required": false; }; "hint": { "alias": "hint"; "required": false; }; "accept": { "alias": "accept"; "required": false; }; "grouped": { "alias": "grouped"; "required": false; }; "required": { "alias": "required"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "hideErrors": { "alias": "hideErrors"; "required": false; }; "items": { "alias": "items"; "required": false; }; }, { "delete": "delete"; }, never, never, true, never>;
|
|
52
52
|
static ngAcceptInputType_grouped: unknown;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { map, startWith, distinctUntilChanged, shareReplay, tap, delay, switchMap } from 'rxjs/operators';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
3
|
import { Directive, Optional, Self, InjectionToken, Input, EventEmitter, Component, ChangeDetectionStrategy, ViewEncapsulation, Inject, Output, booleanAttribute, ContentChild, Host, HostBinding, inject, Renderer2, numberAttribute, HostListener, ElementRef, ViewContainerRef, EnvironmentInjector, Pipe, LOCALE_ID, forwardRef, ViewChild, ChangeDetectorRef, makeEnvironmentProviders, NgModule } from '@angular/core';
|
|
4
|
-
import * as i2 from 'rxjs';
|
|
4
|
+
import * as i2$1 from 'rxjs';
|
|
5
5
|
import { fromEvent, merge, EMPTY, BehaviorSubject, combineLatest, of, Subscription, takeUntil } from 'rxjs';
|
|
6
6
|
import * as i1 from '@angular/forms';
|
|
7
7
|
import { NgControl, Validators, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
|
|
8
|
-
import * as i1$
|
|
8
|
+
import * as i1$2 from '@bravobit/bb-foundation/localize';
|
|
9
9
|
import { BbLocalize, Localize, BbLocalizeTemplate, BbLocalizeString, LOCALIZE_ID } from '@bravobit/bb-foundation/localize';
|
|
10
10
|
import { AsyncPipe, DOCUMENT, formatDate, NgTemplateOutlet } from '@angular/common';
|
|
11
11
|
import { BbTemplate } from '@bravobit/bb-foundation/utils';
|
|
12
12
|
import * as i1$1 from '@angular/cdk/platform';
|
|
13
13
|
import { Platform } from '@angular/cdk/platform';
|
|
14
|
-
import * as
|
|
14
|
+
import * as i2 from '@bravobit/bb-foundation';
|
|
15
15
|
import { Files, clamp, hsvToHex, hexToHsv, Exif, FileLoader, parseDate } from '@bravobit/bb-foundation';
|
|
16
16
|
import { Overlay } from '@angular/cdk/overlay';
|
|
17
17
|
import { ComponentPortal } from '@angular/cdk/portal';
|
|
@@ -829,7 +829,7 @@ class BbFileImage {
|
|
|
829
829
|
return null;
|
|
830
830
|
});
|
|
831
831
|
}
|
|
832
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BbFileImage, deps: [{ token: i1$1.Platform }, { token:
|
|
832
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BbFileImage, deps: [{ token: i1$1.Platform }, { token: i2.ImageConverter }, { token: i3.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
833
833
|
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.6", ngImport: i0, type: BbFileImage, isStandalone: true, name: "bbFileImage" });
|
|
834
834
|
}
|
|
835
835
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BbFileImage, decorators: [{
|
|
@@ -837,7 +837,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImpor
|
|
|
837
837
|
args: [{
|
|
838
838
|
name: 'bbFileImage'
|
|
839
839
|
}]
|
|
840
|
-
}], ctorParameters: () => [{ type: i1$1.Platform }, { type:
|
|
840
|
+
}], ctorParameters: () => [{ type: i1$1.Platform }, { type: i2.ImageConverter }, { type: i3.DomSanitizer }] });
|
|
841
841
|
|
|
842
842
|
class BbFileDataUrl {
|
|
843
843
|
// Dependencies.
|
|
@@ -958,7 +958,7 @@ class BbRelativeTime {
|
|
|
958
958
|
date?.getMonth() === tomorrow?.getMonth() &&
|
|
959
959
|
date?.getFullYear() === tomorrow?.getFullYear();
|
|
960
960
|
};
|
|
961
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BbRelativeTime, deps: [{ token: LOCALE_ID }, { token: i1$
|
|
961
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BbRelativeTime, deps: [{ token: LOCALE_ID }, { token: i1$2.Localize, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
962
962
|
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.6", ngImport: i0, type: BbRelativeTime, isStandalone: true, name: "bbRelativeTime" });
|
|
963
963
|
}
|
|
964
964
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BbRelativeTime, decorators: [{
|
|
@@ -969,7 +969,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImpor
|
|
|
969
969
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
970
970
|
type: Inject,
|
|
971
971
|
args: [LOCALE_ID]
|
|
972
|
-
}] }, { type: i1$
|
|
972
|
+
}] }, { type: i1$2.Localize, decorators: [{
|
|
973
973
|
type: Optional
|
|
974
974
|
}] }] });
|
|
975
975
|
|
|
@@ -1697,8 +1697,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImpor
|
|
|
1697
1697
|
|
|
1698
1698
|
let nextUniqueId$2 = 0;
|
|
1699
1699
|
class BbMultiFileControl {
|
|
1700
|
-
|
|
1701
|
-
|
|
1700
|
+
// Dependencies.
|
|
1701
|
+
_files = inject(Files);
|
|
1702
|
+
_changeDetectorRef = inject(ChangeDetectorRef);
|
|
1703
|
+
_config = inject(ELEMENTS_CONFIG, { optional: true });
|
|
1702
1704
|
// Readonly data.
|
|
1703
1705
|
labelId = `bb-multi-file-control-${nextUniqueId$2++}`;
|
|
1704
1706
|
// Views.
|
|
@@ -1706,7 +1708,7 @@ class BbMultiFileControl {
|
|
|
1706
1708
|
// Inputs.
|
|
1707
1709
|
label = null;
|
|
1708
1710
|
hint = null;
|
|
1709
|
-
accept =
|
|
1711
|
+
accept = this.getAcceptString();
|
|
1710
1712
|
grouped = false;
|
|
1711
1713
|
required = false;
|
|
1712
1714
|
disabled = false;
|
|
@@ -1720,10 +1722,6 @@ class BbMultiFileControl {
|
|
|
1720
1722
|
// Callbacks.
|
|
1721
1723
|
onTouchedCallback = () => ({});
|
|
1722
1724
|
onChangeCallback = () => ({});
|
|
1723
|
-
constructor(_files, _changeDetectorRef) {
|
|
1724
|
-
this._files = _files;
|
|
1725
|
-
this._changeDetectorRef = _changeDetectorRef;
|
|
1726
|
-
}
|
|
1727
1725
|
get showList() {
|
|
1728
1726
|
return this.value?.length > 0 || this.items?.length > 0;
|
|
1729
1727
|
}
|
|
@@ -1760,7 +1758,7 @@ class BbMultiFileControl {
|
|
|
1760
1758
|
this.error = !!error;
|
|
1761
1759
|
}
|
|
1762
1760
|
validate({ value }) {
|
|
1763
|
-
const regexString = (this.accept
|
|
1761
|
+
const regexString = (this.accept ?? '*')
|
|
1764
1762
|
.replace(/\*/g, '.\*')
|
|
1765
1763
|
.replace(/,/g, '|');
|
|
1766
1764
|
const mimeTypeRegex = new RegExp(regexString);
|
|
@@ -1790,7 +1788,13 @@ class BbMultiFileControl {
|
|
|
1790
1788
|
return 'File' in window && input instanceof File
|
|
1791
1789
|
|| 'Blob' in window && input instanceof Blob;
|
|
1792
1790
|
}
|
|
1793
|
-
|
|
1791
|
+
getAcceptString() {
|
|
1792
|
+
const allowedFileTypes = this._config?.allowedFileTypes ?? [];
|
|
1793
|
+
return allowedFileTypes?.length <= 0
|
|
1794
|
+
? null
|
|
1795
|
+
: allowedFileTypes.join(', ');
|
|
1796
|
+
}
|
|
1797
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BbMultiFileControl, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1794
1798
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: BbMultiFileControl, isStandalone: true, selector: "bb-multi-file-control", inputs: { label: "label", hint: "hint", accept: "accept", grouped: ["grouped", "grouped", booleanAttribute], required: ["required", "required", booleanAttribute], disabled: ["disabled", "disabled", booleanAttribute], hideErrors: ["hideErrors", "hideErrors", booleanAttribute], items: "items" }, outputs: { delete: "delete" }, host: { properties: { "class.required": "required", "class.disabled": "disabled", "class.grouped": "grouped", "class.error": "error" }, classAttribute: "bb-multi-file-control" }, providers: [
|
|
1795
1799
|
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => BbMultiFileControl), multi: true },
|
|
1796
1800
|
{ provide: NG_VALIDATORS, useExisting: BbMultiFileControl, multi: true }
|
|
@@ -1808,7 +1812,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImpor
|
|
|
1808
1812
|
'[class.grouped]': 'grouped',
|
|
1809
1813
|
'[class.error]': 'error'
|
|
1810
1814
|
}, imports: [BbFormError, BbTemplate, BbButton, BbLocalize, BbLocalizeTemplate, BbLocalizeString, BbFileDrop], template: "<!-- The label of the input. -->\n@if (label; as labelContent) {\n <label [for]=\"labelId\"\n class=\"bb-multi-file-control-label\">\n <ng-template [bbTemplate]=\"labelContent\">{{ labelContent }}</ng-template>\n </label>\n}\n\n<input #fileInput\n [id]=\"labelId\"\n [accept]=\"accept\"\n [disabled]=\"disabled\"\n (change)=\"onFileChange($event)\"\n class=\"bb-multi-file-control-input\"\n type=\"file\"\n tabindex=\"-1\"\n multiple>\n\n<div [bbFileDropDisabled]=\"disabled\"\n (bbFileDrop)=\"addFiles($event)\"\n class=\"bb-multi-file-control-container\">\n @if (showList) {\n <ul class=\"bb-multi-file-control-list\">\n @for (item of items; track item?.id) {\n <li class=\"bb-multi-file-control-item\">\n <i class=\"bb-multi-file-control-icon attach-horizontal\"></i>\n <a [href]=\"item?.url\"\n target=\"_blank\"\n rel=\"noopener\"\n class=\"bb-multi-file-control-item-content\">{{ item?.label }}</a>\n @if (!disabled && delete?.observed) {\n <button (click)=\"delete?.emit(item)\"\n type=\"button\"\n class=\"bb-multi-file-control-item-button\">\n <i class=\"bb-multi-file-control-icon clear\"></i>\n </button>\n }\n </li>\n }\n @for (file of value; track $index) {\n <li class=\"bb-multi-file-control-item\">\n <i class=\"bb-multi-file-control-icon attach-horizontal\"></i>\n <button (click)=\"downloadFile(file)\"\n class=\"bb-multi-file-control-item-content\"\n type=\"button\">\n {{ file?.name }}\n </button>\n @if (!disabled) {\n <button (click)=\"deleteFile($index)\"\n type=\"button\"\n class=\"bb-multi-file-control-item-button\">\n <i class=\"bb-multi-file-control-icon clear\"></i>\n </button>\n }\n </li>\n }\n </ul>\n } @else if (!disabled) {\n <i class=\"bb-multi-file-control-icon attach-vertical\"></i>\n <p [bb-localize-string]=\"'multi-file-control.choose_file_text' | bbLocalize\"\n class=\"bb-multi-file-control-empty\">\n <label *bbLocalizeTemplate=\"'label'\"\n [for]=\"labelId\">{{ 'multi-file-control.choose_file' | bbLocalize }}</label>\n </p>\n }\n @if (!disabled) {\n <button (click)=\"openFileDialog()\"\n type=\"button\"\n class=\"primary small bb-multi-file-control-button\"\n bb-button>\n <i class=\"bb-multi-file-control-icon add\" suffix></i>\n {{ 'multi-file-control.choose_file' | bbLocalize }}\n </button>\n }\n</div>\n\n@if (!hideErrors) {\n <bb-form-error (errorChange)=\"onErrorChange($event)\"></bb-form-error>\n}\n\n<!-- The file picker hint. -->\n@if (hint; as hintContent) {\n <p class=\"bb-multi-file-control-hint\">\n <ng-template [bbTemplate]=\"hintContent\">{{ hintContent }}</ng-template>\n </p>\n}\n", styles: [".bb-multi-file-control{display:block;line-height:normal}.bb-multi-file-control.grouped{margin-bottom:1.5rem}.bb-multi-file-control.required>.bb-multi-file-control-label:after{content:\"*\";font-size:.75rem;vertical-align:top;color:var(--bb-form-label-required-color)}.bb-multi-file-control-container.is-hovered{border-color:var(--bb-multi-file-control-focus-border-color);box-shadow:0 .375rem .375rem -.375rem #0000001a,var(--bb-multi-file-control-box-shadow)}.bb-multi-file-control.disabled>.bb-multi-file-control-container{cursor:default;color:var(--bb-control-disabled-color);background-color:var(--bb-control-disabled-background-color)}.bb-multi-file-control.error>.bb-multi-file-control-label{color:var(--bb-control-error-color)}.bb-multi-file-control.error>.bb-multi-file-control-hint{display:none}.bb-multi-file-control.error>.bb-multi-file-control-container{border:1px solid var(--bb-control-error-border-color);background-color:var(--bb-control-error-background-color)}.bb-multi-file-control-label{display:block;margin-bottom:.25rem;color:var(--bb-form-label-color);font-size:var(--bb-form-label-font-size);font-weight:var(--bb-form-label-font-weight)}.bb-multi-file-control-input{opacity:0;z-index:-1;width:.1px;height:.1px;overflow:hidden;position:absolute}.bb-multi-file-control-container{width:100%;display:flex;color:#111;padding:.5rem;overflow:hidden;min-height:7.5rem;align-items:center;border-radius:.5rem;flex-direction:column;justify-content:center;background-color:#fff;transition-duration:.25s;transition-property:background-color,box-shadow;transition-timing-function:cubic-bezier(0,0,.2,1);border:1px solid var(--bb-multi-file-control-border-color);box-shadow:0 .375rem .375rem -.375rem #0000001a}.bb-multi-file-control-button{margin-top:.5rem}.bb-multi-file-control-list{flex:1;width:100%;overflow:hidden}.bb-multi-file-control-empty{flex:1;width:100%;color:#758795;display:block;font-weight:400;line-height:1.5;text-align:center;font-size:.875rem}.bb-multi-file-control-empty>label{cursor:pointer;display:inline;font-size:inherit;font-weight:inherit;text-decoration:underline;color:var(--bb-multi-file-control-color)}.bb-multi-file-control-item{height:2rem;display:flex;max-width:100%;overflow:hidden;align-items:center;white-space:nowrap;border-radius:.5rem;text-overflow:ellipsis;padding:0 .25rem 0 .5rem;background-color:#edf4fd;border:1px solid var(--bb-multi-file-control-border-color)}.bb-multi-file-control-item:not(:last-child){margin-bottom:.25rem}.bb-multi-file-control-item-content{flex:1;padding:0;border:none;max-width:100%;margin:0 .5rem;overflow:hidden;appearance:none;text-align:left;font-weight:400;font-size:.875rem;white-space:nowrap;text-decoration:none;text-overflow:ellipsis;background-color:transparent}.bb-multi-file-control-item-content,.bb-multi-file-control-item-content:visited{color:#0a305c}.bb-multi-file-control-item-content:hover,.bb-multi-file-control-item-content:focus{text-decoration:underline}.bb-multi-file-control-item-button{padding:0;width:1.5rem;display:flex;height:1.5rem;align-items:center;border-radius:.25rem;justify-content:center;border:1px solid hsl(0,73%,25%);background-color:#b51c1c}.bb-multi-file-control-item-button:hover,.bb-multi-file-control-item-button:focus{background-color:#a81a1a}.bb-multi-file-control-item-button:active{background-color:#9a1818}.bb-multi-file-control-hint{display:block;line-height:1.5;margin-top:.25rem;font-size:.8125rem;color:#758795}.bb-multi-file-control-icon{width:1.25rem;height:1.25rem;display:inline-flex;background-size:contain;background-repeat:no-repeat;background-position:center center}.bb-multi-file-control-icon.add{background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" fill=\"%23fff\" viewBox=\"0 0 24 24\"%3E%3Cpath d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\"/%3E%3C/svg%3E')}.bb-multi-file-control-icon.attach-vertical{width:1.5rem;height:1.5rem;margin-bottom:.5rem;background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" fill=\"%23758795\" viewBox=\"0 0 24 24\"%3E%3Cpath d=\"M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z\"/%3E%3C/svg%3E')}.bb-multi-file-control-icon.attach-horizontal{background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"%3E%3Cpath d=\"M2 12.5C2 9.46 4.46 7 7.5 7H18c2.21 0 4 1.79 4 4s-1.79 4-4 4H9.5C8.12 15 7 13.88 7 12.5S8.12 10 9.5 10H17v2H9.41c-.55 0-.55 1 0 1H18c1.1 0 2-.9 2-2s-.9-2-2-2H7.5C5.57 9 4 10.57 4 12.5S5.57 16 7.5 16H17v2H7.5C4.46 18 2 15.54 2 12.5z\"/%3E%3C/svg%3E')}.bb-multi-file-control-icon.clear{background-image:url('data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" fill=\"%23fff\" viewBox=\"0 0 24 24\"%3E%3Cpath d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/%3E%3C/svg%3E')}\n"] }]
|
|
1811
|
-
}],
|
|
1815
|
+
}], propDecorators: { fileInput: [{
|
|
1812
1816
|
type: ViewChild,
|
|
1813
1817
|
args: ['fileInput', { static: true }]
|
|
1814
1818
|
}], label: [{
|
|
@@ -1837,6 +1841,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImpor
|
|
|
1837
1841
|
|
|
1838
1842
|
let nextUniqueId$1 = 0;
|
|
1839
1843
|
class BbFilePicker {
|
|
1844
|
+
// Dependencies.
|
|
1845
|
+
_config = inject(ELEMENTS_CONFIG, { optional: true });
|
|
1840
1846
|
// Readonly data.
|
|
1841
1847
|
labelId = `bb-file-picker-${nextUniqueId$1++}`;
|
|
1842
1848
|
// Views.
|
|
@@ -1845,7 +1851,7 @@ class BbFilePicker {
|
|
|
1845
1851
|
// Inputs.
|
|
1846
1852
|
label = null;
|
|
1847
1853
|
hint = null;
|
|
1848
|
-
accept =
|
|
1854
|
+
accept = this.getAcceptString();
|
|
1849
1855
|
showImages = true;
|
|
1850
1856
|
grouped = false;
|
|
1851
1857
|
required = false;
|
|
@@ -1911,7 +1917,7 @@ class BbFilePicker {
|
|
|
1911
1917
|
if (value === null || value === undefined) {
|
|
1912
1918
|
return null;
|
|
1913
1919
|
}
|
|
1914
|
-
const regexString = (this.accept
|
|
1920
|
+
const regexString = (this.accept ?? '*')
|
|
1915
1921
|
.replace(/\*/g, '.\*')
|
|
1916
1922
|
.replace(/,/g, '|');
|
|
1917
1923
|
const mimeTypeRegex = new RegExp(regexString);
|
|
@@ -1933,6 +1939,12 @@ class BbFilePicker {
|
|
|
1933
1939
|
}
|
|
1934
1940
|
return Array.from(element.files);
|
|
1935
1941
|
}
|
|
1942
|
+
getAcceptString() {
|
|
1943
|
+
const allowedFileTypes = this._config?.allowedFileTypes ?? [];
|
|
1944
|
+
return allowedFileTypes?.length <= 0
|
|
1945
|
+
? null
|
|
1946
|
+
: allowedFileTypes.join(', ');
|
|
1947
|
+
}
|
|
1936
1948
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BbFilePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1937
1949
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: BbFilePicker, isStandalone: true, selector: "bb-file-picker", inputs: { label: "label", hint: "hint", accept: "accept", showImages: "showImages", grouped: ["grouped", "grouped", booleanAttribute], required: ["required", "required", booleanAttribute], disabled: ["disabled", "disabled", booleanAttribute], hideErrors: ["hideErrors", "hideErrors", booleanAttribute], value: "value" }, outputs: { valueChange: "valueChange" }, host: { properties: { "class.required": "required", "class.disabled": "disabled", "class.grouped": "grouped", "class.error": "error" }, classAttribute: "bb-file-picker" }, providers: [
|
|
1938
1950
|
{
|
|
@@ -2090,7 +2102,7 @@ class BbImagePicker {
|
|
|
2090
2102
|
setDisabledState(isDisabled) {
|
|
2091
2103
|
this.disabled = isDisabled;
|
|
2092
2104
|
}
|
|
2093
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BbImagePicker, deps: [{ token:
|
|
2105
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BbImagePicker, deps: [{ token: i2.ImageConverter }], target: i0.ɵɵFactoryTarget.Component });
|
|
2094
2106
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: BbImagePicker, isStandalone: true, selector: "bb-image-picker", inputs: { label: "label", placeholder: "placeholder", styleDimensions: "styleDimensions", cropDimensions: "cropDimensions", buttonClass: "buttonClass", disabled: ["disabled", "disabled", booleanAttribute], grouped: ["grouped", "grouped", booleanAttribute], value: "value" }, outputs: { valueChange: "valueChange" }, host: { properties: { "class.disabled": "disabled", "class.grouped": "grouped" }, classAttribute: "bb-image-picker" }, providers: [
|
|
2095
2107
|
{
|
|
2096
2108
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -2112,7 +2124,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImpor
|
|
|
2112
2124
|
multi: true
|
|
2113
2125
|
}
|
|
2114
2126
|
], imports: [BbButton, AsyncPipe], template: "<!-- The input that can open the file picker. -->\n<input #fileInput\n (change)=\"onFileChange($event)\"\n class=\"bb-image-picker-input\"\n type=\"file\"\n tabindex=\"-1\"\n accept=\"image/*\">\n\n<span [style.width]=\"styleDimensions?.width ?? '100%'\"\n [style.height]=\"styleDimensions?.height ?? '215px'\"\n [style.background-image]=\"image | async\"\n class=\"bb-image-input-image\"></span>\n\n@if (label; as labelText) {\n <button (click)=\"openFilePicker()\"\n bb-button\n class=\"bb-image-input-button {{ buttonClass }}\"\n type=\"button\">\n {{ labelText }}\n </button>\n}\n", styles: [".bb-image-picker{display:flex;align-items:center;line-height:normal;flex-direction:column}.bb-image-picker.circle>.bb-image-input-image{border-radius:50%}.bb-image-picker.grouped{margin-bottom:1.5rem}.bb-image-picker.disabled{opacity:.5;cursor:default;-webkit-user-select:none;user-select:none;pointer-events:none}.bb-image-picker-input{opacity:0;z-index:-1;width:.1px;height:.1px;overflow:hidden;position:absolute}.bb-image-input-image{display:flex;cursor:default;position:relative;align-items:center;border-radius:.25rem;justify-content:center;background:#0003 url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7) center center/cover no-repeat}.bb-image-input-button{margin-top:.75rem}\n"] }]
|
|
2115
|
-
}], ctorParameters: () => [{ type:
|
|
2127
|
+
}], ctorParameters: () => [{ type: i2.ImageConverter }], propDecorators: { fileInput: [{
|
|
2116
2128
|
type: ViewChild,
|
|
2117
2129
|
args: ['fileInput', { static: true }]
|
|
2118
2130
|
}], label: [{
|
|
@@ -2411,7 +2423,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImpor
|
|
|
2411
2423
|
BbInput,
|
|
2412
2424
|
BbFormError
|
|
2413
2425
|
], template: "<!-- Label of the date picker. -->\n@if (label; as labelContent) {\n <label class=\"bb-date-picker-label\">\n <ng-template [bbTemplate]=\"labelContent\">{{ labelContent }}</ng-template>\n </label>\n}\n\n@if (data$ | async; as data) {\n <!-- The form containing the year/month/day fields. -->\n <div [formGroup]=\"form\"\n class=\"bb-date-picker-container\">\n <div class=\"bb-date-picker-item\">\n <bb-form-control hideErrors>\n <select [class.has-value]=\"!!form?.get('day')?.value\"\n bbInput\n autocomplete=\"off\"\n formControlName=\"day\">\n <option [ngValue]=\"null\">{{ dayPlaceholder }}</option>\n @for (day of data?.days; track day?.value) {\n <option [value]=\"day?.value\">{{ day?.label }}</option>\n }\n </select>\n </bb-form-control>\n </div>\n <div class=\"bb-date-picker-item\">\n <bb-form-control hideErrors>\n <select [class.has-value]=\"!!form?.get('month')?.value\"\n bbInput\n autocomplete=\"off\"\n formControlName=\"month\">\n <option [ngValue]=\"null\">{{ monthPlaceholder }}</option>\n @for (month of data?.months; track month?.value) {\n <option [value]=\"month?.value\">{{ month?.label }}</option>\n }\n </select>\n </bb-form-control>\n </div>\n <div class=\"bb-date-picker-item\">\n <bb-form-control hideErrors>\n @if (data?.years?.length > 0) {\n <select [class.has-value]=\"!!form?.get('year')?.value\"\n bbInput\n autocomplete=\"off\"\n formControlName=\"year\">\n <option [ngValue]=\"null\">{{ yearPlaceholder }}</option>\n @for (year of data?.years; track year) {\n <option [value]=\"year\">{{ year }}</option>\n }\n </select>\n } @else {\n <input [placeholder]=\"yearPlaceholder\"\n bbInput\n type=\"text\"\n inputmode=\"numeric\"\n minlength=\"4\"\n maxlength=\"4\"\n pattern=\"^[0-9]{4}$\"\n formControlName=\"year\"\n autocomplete=\"off\">\n }\n </bb-form-control>\n </div>\n </div>\n}\n\n<!-- The date picker error. -->\n@if (!hideErrors) {\n <bb-form-error (errorChange)=\"onErrorChange($event)\"></bb-form-error>\n}\n<!-- The date picker hint. -->\n@if (hint; as hintContent) {\n <p class=\"bb-date-picker-hint\">\n <ng-template [bbTemplate]=\"hintContent\">{{ hintContent }}</ng-template>\n </p>\n}\n", styles: [".bb-date-picker{display:block;line-height:normal}.bb-date-picker.required>.bb-date-picker-label:after{content:\"*\";font-size:.75rem;vertical-align:top;color:var(--bb-form-label-required-color)}.bb-date-picker.readonly{pointer-events:none}.bb-date-picker.readonly>.bb-date-picker-container>.bb-date-picker-item>.bb-form-control>.bb-form-control-container{cursor:default;border-style:dotted;border-color:#bdc4c9}.bb-date-picker.readonly>.bb-date-picker-container>.bb-date-picker-item>.bb-form-control>.bb-form-control-container>select:disabled{opacity:1}.bb-date-picker.grouped{margin-bottom:1.5rem}.bb-date-picker.error>.bb-date-picker-label{color:var(--bb-control-error-color)}.bb-date-picker.error>.bb-date-picker-container>.bb-date-picker-item>.bb-form-control>.bb-form-control-container{border-color:var(--bb-control-error-border-color);background-color:var(--bb-control-error-background-color)}.bb-date-picker.error>.bb-date-picker-container>.bb-date-picker-item>.bb-form-control>.bb-form-control-container>input::placeholder,.bb-date-picker.error>.bb-date-picker-container>.bb-date-picker-item>.bb-form-control>.bb-form-control-container>textarea::placeholder,.bb-date-picker.error>.bb-date-picker-container>.bb-date-picker-item>.bb-form-control>.bb-form-control-container>select:not(.has-value){color:var(--bb-control-error-placeholder-color)}.bb-date-picker.error>.bb-date-picker-container>.bb-date-picker-item>.bb-form-control>.bb-form-control-container:has(input:not(:disabled):not(:read-only):focus,select:not(:disabled):focus){box-shadow:var(--bb-control-error-box-shadow)}.bb-date-picker-label{display:block;margin-bottom:.25rem;color:var(--bb-form-label-color, #525252);font-weight:var(--bb-form-label-font-weight, 400);font-size:var(--bb-form-label-font-size, .875rem)}.bb-date-picker-container{display:flex}.bb-date-picker-item{flex:1}.bb-date-picker-item>.bb-form-control>.bb-form-control-container:has(input:not(:disabled):not(:read-only):focus,select:not(:disabled):focus){z-index:1;position:relative}.bb-date-picker-item>.bb-form-control>.bb-form-control-container>select>option:first-child{color:#d2d2d2}.bb-date-picker-item>.bb-form-control>.bb-form-control-container>select:not(.has-value){color:#d2d2d2}.bb-date-picker-item>.bb-form-control>.bb-form-control-container>select:not(.has-value)>option:not(:first-child){color:#111}.bb-date-picker-item:not(:first-child):not(:last-child){margin:0 -1px}.bb-date-picker-item:not(:first-child):not(:last-child)>.bb-form-control>.bb-form-control-container{border-radius:0}.bb-date-picker-item:first-child>.bb-form-control>.bb-form-control-container{border-top-right-radius:0;border-bottom-right-radius:0}.bb-date-picker-item:last-child>.bb-form-control>.bb-form-control-container{border-top-left-radius:0;border-bottom-left-radius:0}.bb-date-picker-hint{display:block;line-height:1.5;margin-top:.25rem;font-size:.8125rem;color:#758795}\n"] }]
|
|
2414
|
-
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i2.Observable, decorators: [{
|
|
2426
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i2$1.Observable, decorators: [{
|
|
2415
2427
|
type: Inject,
|
|
2416
2428
|
args: [LOCALIZE_ID]
|
|
2417
2429
|
}] }], propDecorators: { label: [{
|