@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.
@@ -34,5 +34,6 @@ export interface ElementsConfig {
34
34
  iconFonts?: ElementsIcon[];
35
35
  errors?: ElementsError;
36
36
  defaultDisplayUnit?: ElementsDisplayUnit;
37
+ allowedFileTypes?: string[];
37
38
  }
38
39
  export type ElementsDisplayUnit = 'rem' | 'px';
@@ -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 | null;
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 { ChangeDetectorRef, ElementRef, EventEmitter, TemplateRef } from '@angular/core';
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 | null;
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$3 from '@bravobit/bb-foundation/localize';
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 i1$2 from '@bravobit/bb-foundation';
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: i1$2.ImageConverter }, { token: i3.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
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: i1$2.ImageConverter }, { type: i3.DomSanitizer }] });
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$3.Localize, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
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$3.Localize, decorators: [{
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
- _files;
1701
- _changeDetectorRef;
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 = null;
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
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: BbMultiFileControl, deps: [{ token: i1$2.Files }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
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
- }], ctorParameters: () => [{ type: i1$2.Files }, { type: i0.ChangeDetectorRef }], propDecorators: { fileInput: [{
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 = null;
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: i1$2.ImageConverter }], target: i0.ɵɵFactoryTarget.Component });
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: i1$2.ImageConverter }], propDecorators: { fileInput: [{
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: [{