@bitforgehq/ui 0.3.1 → 0.3.2

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/README.md +9 -8
  3. package/ai/MANIFEST.index.json +18 -0
  4. package/ai/MANIFEST.json +368 -31
  5. package/ai/REFERENCE.index.json +63 -0
  6. package/ai/REFERENCE.json +247 -5
  7. package/ai/UI_GUIDE.md +59 -33
  8. package/ai/components/app-frame.md +328 -0
  9. package/ai/components/card.md +56 -2
  10. package/ai/components/empty-state.md +99 -6
  11. package/ai/components/header.md +5 -1
  12. package/ai/components/sidebar-toggle.md +287 -0
  13. package/ai/components/sidebar.md +188 -10
  14. package/ai/components/stat.md +74 -10
  15. package/ai/components/table.md +134 -5
  16. package/ai/components/tabs.md +5 -1
  17. package/ai/components/toolbar.md +69 -4
  18. package/ai/reference/bf-app-frame-breakpoint.md +27 -0
  19. package/ai/reference/bf-app-frame-content-width.md +29 -0
  20. package/ai/reference/bf-empty-state-heading-level.md +1 -1
  21. package/ai/reference/bf-empty-state-heading.md +33 -0
  22. package/ai/reference/bf-labels.md +6 -0
  23. package/ai/reference/bf-sidebar-state-service.md +21 -0
  24. package/ai/reference/bf-sidebar-toggle-harness.md +32 -0
  25. package/ai/reference/bf-size.md +1 -0
  26. package/ai/reference/bf-stat-appearance.md +33 -0
  27. package/ai/reference/bf-stat-variant.md +1 -1
  28. package/ai/reference/bf-table-harness.md +1 -1
  29. package/ai/reference/bf-table-stack.md +29 -0
  30. package/ai/reference/bf_sidebar_state_storage.md +20 -0
  31. package/ai/reference/provide-bf-labels.md +4 -3
  32. package/ai/reference/provide-bf-sidebar-state.md +20 -0
  33. package/bin/bf-ui.js +433 -3
  34. package/fesm2022/bitforgehq-ui-overlay.mjs +571 -446
  35. package/fesm2022/bitforgehq-ui-overlay.mjs.map +1 -1
  36. package/fesm2022/bitforgehq-ui-testing.mjs +18 -2
  37. package/fesm2022/bitforgehq-ui-testing.mjs.map +1 -1
  38. package/fesm2022/bitforgehq-ui.mjs +759 -127
  39. package/fesm2022/bitforgehq-ui.mjs.map +1 -1
  40. package/llms-full.txt +1560 -43
  41. package/llms.txt +11 -0
  42. package/package.json +1 -1
  43. package/types/bitforgehq-ui-overlay.d.ts +51 -0
  44. package/types/bitforgehq-ui-testing.d.ts +35 -1
  45. package/types/bitforgehq-ui.d.ts +276 -20
@@ -4,7 +4,7 @@ import { FocusTrapFactory, LiveAnnouncer } from "@angular/cdk/a11y";
4
4
  import { Overlay, OverlayConfig } from "@angular/cdk/overlay";
5
5
  import { ComponentPortal, TemplatePortal } from "@angular/cdk/portal";
6
6
  import { Location, NgTemplateOutlet } from "@angular/common";
7
- import { BF_DEFAULTS, BF_LABELS, BfButtonComponent, BfCalendarComponent, BfFieldComponent, BfIconButtonComponent, BfSpinnerComponent, bfFieldControlClass, ɵBF_BUTTON_CLASSES, ɵBF_ICON_BUTTON_CLASSES, ɵFIELD_BOX, ɵFIELD_PADDING_END, ɵFIELD_PADDING_START, ɵPILL_HIT, ɵdaysInMonth, ɵfieldDescribedBy, ɵfieldErrorMessageId, ɵfieldErrorText, ɵfieldShowsError, ɵformatIsoDate, ɵlocalIsoDate, ɵparseIsoDate, ɵuniqueId } from "@bitforgehq/ui";
7
+ import { BF_DEFAULTS, BF_LABELS, BfButtonComponent, BfCalendarComponent, BfFieldComponent, BfIconButtonComponent, BfSpinnerComponent, bfFieldControlClass, ɵBF_BUTTON_CLASSES, ɵBF_ICON_BUTTON_CLASSES, ɵBF_NAV, ɵFIELD_BOX, ɵFIELD_PADDING_END, ɵFIELD_PADDING_START, ɵPILL_HIT, ɵdaysInMonth, ɵfieldDescribedBy, ɵfieldErrorMessageId, ɵfieldErrorText, ɵfieldShowsError, ɵformatIsoDate, ɵlocalIsoDate, ɵparseIsoDate, ɵuniqueId } from "@bitforgehq/ui";
8
8
  import { BfIconComponent } from "@bitforgehq/ui/icons";
9
9
  import { X } from "lucide";
10
10
  import { Directionality } from "@angular/cdk/bidi";
@@ -2509,7 +2509,7 @@ i0.ɵɵngDeclareClassMetadata({
2509
2509
  }]
2510
2510
  });
2511
2511
  const BUTTON = ɵBF_BUTTON_CLASSES;
2512
- const ICON = ɵBF_ICON_BUTTON_CLASSES;
2512
+ const ICON$1 = ɵBF_ICON_BUTTON_CLASSES;
2513
2513
  const CARET_PADDING = {
2514
2514
  sm: "ps-3.5 pe-3",
2515
2515
  md: "ps-4.5 pe-4",
@@ -2539,12 +2539,12 @@ var BfMenuButtonComponent = class BfMenuButtonComponent {
2539
2539
  const variant = this.variant();
2540
2540
  const hit = ɵPILL_HIT[size][variant === "outline" ? "bordered" : "plain"];
2541
2541
  if (this.iconOnly()) {
2542
- const pressed = this.disabled() ? "" : ICON.pressed[variant];
2542
+ const pressed = this.disabled() ? "" : ICON$1.pressed[variant];
2543
2543
  return [
2544
- ICON.base,
2545
- ICON.variant[variant],
2544
+ ICON$1.base,
2545
+ ICON$1.variant[variant],
2546
2546
  pressed,
2547
- ICON.size[size],
2547
+ ICON$1.size[size],
2548
2548
  hit
2549
2549
  ].filter(Boolean).join(" ");
2550
2550
  }
@@ -3028,468 +3028,52 @@ i0.ɵɵngDeclareClassMetadata({
3028
3028
  }]
3029
3029
  }
3030
3030
  });
3031
- const BF_SIDE_PANEL_DATA = new InjectionToken("BF_SIDE_PANEL_DATA");
3032
- const BF_SIDE_PANEL_CONTEXT = new InjectionToken("BF_SIDE_PANEL_CONTEXT");
3033
- var BfSidePanelRef = class {
3034
- overlayRef;
3035
- instance;
3036
- id;
3037
- afterClosed;
3038
- closed;
3039
- constructor(overlayRef, instance = () => null) {
3040
- this.overlayRef = overlayRef;
3041
- this.instance = instance;
3042
- this.id = overlayRef.id;
3043
- this.afterClosed = overlayRef.afterClosed;
3044
- this.closed = overlayRef.closed;
3045
- }
3046
- get componentInstance() {
3047
- return this.instance();
3048
- }
3049
- close(result) {
3050
- this.overlayRef.close(result);
3051
- }
3052
- };
3053
- const HOST_BASE = "relative flex h-full flex-col border-s border-border bg-surface text-text shadow-floating";
3054
- const WIDTH = {
3055
- sm: "w-[min(22.5rem,100vw)]",
3056
- md: "w-[min(30rem,100vw)]",
3057
- lg: "w-[min(40rem,100vw)]"
3058
- };
3059
- var BfSidePanelComponent = class BfSidePanelComponent {
3060
- labels = inject(BF_LABELS);
3061
- context = inject(BF_SIDE_PANEL_CONTEXT, { optional: true });
3062
- ref = inject(BfSidePanelRef, { optional: true });
3063
- title = input("", ...ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []);
3064
- closeLabel = input("", ...ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []);
3065
- overflowing = signal(false, ...ngDevMode ? [{ debugName: "overflowing" }] : /* istanbul ignore next */ []);
3066
- titleId = this.context?.titleId ?? ɵuniqueId("bf-side-panel-title");
3067
- closeIcon = X;
3068
- width = this.context?.width ?? "md";
3069
- hostClasses = computed(() => `${HOST_BASE} ${WIDTH[this.width]}`, ...ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []);
3070
- closeName = computed(() => this.closeLabel() || this.labels.close, ...ngDevMode ? [{ debugName: "closeName" }] : /* istanbul ignore next */ []);
3071
- body = viewChild.required("body", ...ngDevMode ? [{ debugName: "body" }] : /* istanbul ignore next */ []);
3072
- content = viewChild.required("content", ...ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []);
3073
- constructor() {
3074
- let observer = null;
3075
- afterNextRender(() => {
3076
- const body = this.body().nativeElement;
3077
- const measure = () => this.overflowing.set(body.scrollHeight > body.clientHeight);
3078
- measure();
3079
- if (typeof ResizeObserver === "function") {
3080
- observer = new ResizeObserver(measure);
3081
- observer.observe(body);
3082
- observer.observe(this.content().nativeElement);
3083
- }
3084
- });
3085
- inject(DestroyRef).onDestroy(() => observer?.disconnect());
3086
- }
3087
- close() {
3088
- this.ref?.close();
3089
- }
3031
+ var BfTooltipComponent = class BfTooltipComponent {
3032
+ text = input("", ...ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []);
3090
3033
  static ɵfac = i0.ɵɵngDeclareFactory({
3091
3034
  minVersion: "12.0.0",
3092
3035
  version: "22.1.7",
3093
3036
  ngImport: i0,
3094
- type: BfSidePanelComponent,
3037
+ type: BfTooltipComponent,
3095
3038
  deps: [],
3096
3039
  target: i0.ɵɵFactoryTarget.Component
3097
3040
  });
3098
3041
  static ɵcmp = i0.ɵɵngDeclareComponent({
3099
- minVersion: "17.0.0",
3042
+ minVersion: "17.1.0",
3100
3043
  version: "22.1.7",
3101
- type: BfSidePanelComponent,
3044
+ type: BfTooltipComponent,
3102
3045
  isStandalone: true,
3103
- selector: "bf-side-panel",
3104
- inputs: {
3105
- title: {
3106
- classPropertyName: "title",
3107
- publicName: "title",
3108
- isSignal: true,
3109
- isRequired: false,
3110
- transformFunction: null
3111
- },
3112
- closeLabel: {
3113
- classPropertyName: "closeLabel",
3114
- publicName: "closeLabel",
3115
- isSignal: true,
3116
- isRequired: false,
3117
- transformFunction: null
3118
- }
3119
- },
3120
- host: { properties: {
3121
- "class": "hostClasses()",
3122
- "attr.data-bf-side-panel-id": "titleId"
3046
+ selector: "bf-tooltip",
3047
+ inputs: { text: {
3048
+ classPropertyName: "text",
3049
+ publicName: "text",
3050
+ isSignal: true,
3051
+ isRequired: false,
3052
+ transformFunction: null
3123
3053
  } },
3124
- viewQueries: [{
3125
- propertyName: "body",
3126
- first: true,
3127
- predicate: ["body"],
3128
- descendants: true,
3129
- isSignal: true
3130
- }, {
3131
- propertyName: "content",
3132
- first: true,
3133
- predicate: ["content"],
3134
- descendants: true,
3135
- isSignal: true
3136
- }],
3054
+ host: {
3055
+ attributes: { "role": "tooltip" },
3056
+ classAttribute: "block max-w-xs rounded-field border border-transparent bg-tooltip px-2.5 py-1 text-label-xs text-on-tooltip shadow-raised break-words"
3057
+ },
3137
3058
  ngImport: i0,
3138
- template: `
3139
- <div
3140
- data-side-panel-header
3141
- class="border-border flex min-h-16 min-w-0 shrink-0 items-center gap-3 border-b py-4 ps-6 pe-14"
3142
- >
3143
- @if (title()) {
3144
- <h2 [id]="titleId" class="text-heading min-w-0 flex-1 wrap-anywhere">{{ title() }}</h2>
3145
- }
3146
- <ng-content select="[bfSlot=header]" />
3147
- </div>
3148
- <div
3149
- #body
3150
- data-side-panel-body
3151
- class="focus-visible:ring-ring min-h-0 flex-1 overflow-y-auto overscroll-contain px-6 py-4 focus-visible:ring-4 focus-visible:outline-hidden focus-visible:ring-inset"
3152
- [attr.tabindex]="overflowing() ? 0 : null"
3153
- [attr.role]="overflowing() && title() ? 'region' : null"
3154
- [attr.aria-labelledby]="overflowing() && title() ? titleId : null"
3155
- >
3156
- <div #content class="flex flex-col gap-4"><ng-content /></div>
3157
- </div>
3158
- <!-- A projected wrapper (<div bfSlot="footer">) lays out its buttons like the row itself. -->
3159
- <div
3160
- data-side-panel-footer
3161
- class="border-border flex shrink-0 flex-wrap justify-end gap-2 border-t px-6 py-4 *:flex *:min-w-0 *:flex-wrap *:justify-end *:gap-2 empty:hidden"
3162
- >
3163
- <ng-content select="[bfSlot=footer]" />
3164
- </div>
3165
- <!-- Last in DOM order so first-tabbable focus lands on the content, not on the ×. -->
3166
- <bf-icon-button
3167
- data-side-panel-close
3168
- class="absolute end-3 top-4"
3169
- variant="text"
3170
- size="sm"
3171
- [label]="closeName()"
3172
- (clicked)="close()"
3173
- >
3174
- <bf-icon [icon]="closeIcon" />
3175
- </bf-icon-button>
3176
- `,
3177
- isInline: true,
3178
- dependencies: [{
3179
- kind: "component",
3180
- type: BfIconButtonComponent,
3181
- selector: "bf-icon-button, a[bfIconButton]",
3182
- inputs: [
3183
- "variant",
3184
- "size",
3185
- "type",
3186
- "disabled",
3187
- "label"
3188
- ],
3189
- outputs: ["clicked"]
3190
- }, {
3191
- kind: "component",
3192
- type: BfIconComponent,
3193
- selector: "bf-icon",
3194
- inputs: [
3195
- "icon",
3196
- "size",
3197
- "label",
3198
- "filled"
3199
- ]
3200
- }]
3059
+ template: "{{ text() }}",
3060
+ isInline: true
3201
3061
  });
3202
3062
  };
3203
3063
  i0.ɵɵngDeclareClassMetadata({
3204
3064
  minVersion: "12.0.0",
3205
3065
  version: "22.1.7",
3206
3066
  ngImport: i0,
3207
- type: BfSidePanelComponent,
3067
+ type: BfTooltipComponent,
3208
3068
  decorators: [{
3209
3069
  type: Component,
3210
3070
  args: [{
3211
- selector: "bf-side-panel",
3212
- imports: [BfIconButtonComponent, BfIconComponent],
3071
+ selector: "bf-tooltip",
3213
3072
  host: {
3214
- "[class]": "hostClasses()",
3215
- "[attr.data-bf-side-panel-id]": "titleId"
3073
+ role: "tooltip",
3074
+ class: "block max-w-xs rounded-field border border-transparent bg-tooltip px-2.5 py-1 text-label-xs text-on-tooltip shadow-raised break-words"
3216
3075
  },
3217
- template: `
3218
- <div
3219
- data-side-panel-header
3220
- class="border-border flex min-h-16 min-w-0 shrink-0 items-center gap-3 border-b py-4 ps-6 pe-14"
3221
- >
3222
- @if (title()) {
3223
- <h2 [id]="titleId" class="text-heading min-w-0 flex-1 wrap-anywhere">{{ title() }}</h2>
3224
- }
3225
- <ng-content select="[bfSlot=header]" />
3226
- </div>
3227
- <div
3228
- #body
3229
- data-side-panel-body
3230
- class="focus-visible:ring-ring min-h-0 flex-1 overflow-y-auto overscroll-contain px-6 py-4 focus-visible:ring-4 focus-visible:outline-hidden focus-visible:ring-inset"
3231
- [attr.tabindex]="overflowing() ? 0 : null"
3232
- [attr.role]="overflowing() && title() ? 'region' : null"
3233
- [attr.aria-labelledby]="overflowing() && title() ? titleId : null"
3234
- >
3235
- <div #content class="flex flex-col gap-4"><ng-content /></div>
3236
- </div>
3237
- <!-- A projected wrapper (<div bfSlot="footer">) lays out its buttons like the row itself. -->
3238
- <div
3239
- data-side-panel-footer
3240
- class="border-border flex shrink-0 flex-wrap justify-end gap-2 border-t px-6 py-4 *:flex *:min-w-0 *:flex-wrap *:justify-end *:gap-2 empty:hidden"
3241
- >
3242
- <ng-content select="[bfSlot=footer]" />
3243
- </div>
3244
- <!-- Last in DOM order so first-tabbable focus lands on the content, not on the ×. -->
3245
- <bf-icon-button
3246
- data-side-panel-close
3247
- class="absolute end-3 top-4"
3248
- variant="text"
3249
- size="sm"
3250
- [label]="closeName()"
3251
- (clicked)="close()"
3252
- >
3253
- <bf-icon [icon]="closeIcon" />
3254
- </bf-icon-button>
3255
- `
3256
- }]
3257
- }],
3258
- ctorParameters: () => [],
3259
- propDecorators: {
3260
- title: [{
3261
- type: i0.Input,
3262
- args: [{
3263
- isSignal: true,
3264
- alias: "title",
3265
- required: false
3266
- }]
3267
- }],
3268
- closeLabel: [{
3269
- type: i0.Input,
3270
- args: [{
3271
- isSignal: true,
3272
- alias: "closeLabel",
3273
- required: false
3274
- }]
3275
- }],
3276
- body: [{
3277
- type: i0.ViewChild,
3278
- args: ["body", { isSignal: true }]
3279
- }],
3280
- content: [{
3281
- type: i0.ViewChild,
3282
- args: ["content", { isSignal: true }]
3283
- }]
3284
- }
3285
- });
3286
- const BF_SIDE_PANEL_TEMPLATE = new InjectionToken("BF_SIDE_PANEL_TEMPLATE");
3287
- var BfSidePanelTemplateHostComponent = class BfSidePanelTemplateHostComponent {
3288
- view = inject(BF_SIDE_PANEL_TEMPLATE);
3289
- injector = inject(Injector);
3290
- static ɵfac = i0.ɵɵngDeclareFactory({
3291
- minVersion: "12.0.0",
3292
- version: "22.1.7",
3293
- ngImport: i0,
3294
- type: BfSidePanelTemplateHostComponent,
3295
- deps: [],
3296
- target: i0.ɵɵFactoryTarget.Component
3297
- });
3298
- static ɵcmp = i0.ɵɵngDeclareComponent({
3299
- minVersion: "14.0.0",
3300
- version: "22.1.7",
3301
- type: BfSidePanelTemplateHostComponent,
3302
- isStandalone: true,
3303
- selector: "bf-side-panel-template-host",
3304
- host: { styleAttribute: "display: contents" },
3305
- ngImport: i0,
3306
- template: `<ng-container
3307
- [ngTemplateOutlet]="view.template"
3308
- [ngTemplateOutletContext]="view.context"
3309
- [ngTemplateOutletInjector]="injector"
3310
- />`,
3311
- isInline: true,
3312
- dependencies: [{
3313
- kind: "directive",
3314
- type: NgTemplateOutlet,
3315
- selector: "[ngTemplateOutlet]",
3316
- inputs: [
3317
- "ngTemplateOutletContext",
3318
- "ngTemplateOutlet",
3319
- "ngTemplateOutletInjector"
3320
- ]
3321
- }]
3322
- });
3323
- };
3324
- i0.ɵɵngDeclareClassMetadata({
3325
- minVersion: "12.0.0",
3326
- version: "22.1.7",
3327
- ngImport: i0,
3328
- type: BfSidePanelTemplateHostComponent,
3329
- decorators: [{
3330
- type: Component,
3331
- args: [{
3332
- selector: "bf-side-panel-template-host",
3333
- imports: [NgTemplateOutlet],
3334
- host: { style: "display: contents" },
3335
- template: `<ng-container
3336
- [ngTemplateOutlet]="view.template"
3337
- [ngTemplateOutletContext]="view.context"
3338
- [ngTemplateOutletInjector]="injector"
3339
- />`
3340
- }]
3341
- }]
3342
- });
3343
- function exitPanel(el) {
3344
- el.setAttribute("data-bf-closing", "");
3345
- return slideOutToEnd(el);
3346
- }
3347
- var BfSidePanelService = class BfSidePanelService {
3348
- overlays = inject(BfOverlayService);
3349
- injector = inject(Injector);
3350
- open(content, config = {}) {
3351
- const width = config.width ?? "md";
3352
- const injector = config.injector ?? this.injector;
3353
- const titleId = ɵuniqueId("bf-side-panel-title");
3354
- let panelRef = null;
3355
- let instance = null;
3356
- const providers = (ref) => {
3357
- const created = new BfSidePanelRef(ref, () => instance);
3358
- panelRef = created;
3359
- const list = [
3360
- {
3361
- provide: BfSidePanelRef,
3362
- useValue: created
3363
- },
3364
- {
3365
- provide: BF_SIDE_PANEL_DATA,
3366
- useValue: config.data
3367
- },
3368
- {
3369
- provide: BF_SIDE_PANEL_CONTEXT,
3370
- useValue: {
3371
- titleId,
3372
- width
3373
- }
3374
- }
3375
- ];
3376
- if (content instanceof TemplateRef) {
3377
- const view = {
3378
- template: content,
3379
- context: {
3380
- $implicit: created,
3381
- data: config.data
3382
- }
3383
- };
3384
- list.push({
3385
- provide: BF_SIDE_PANEL_TEMPLATE,
3386
- useValue: view
3387
- });
3388
- }
3389
- return list;
3390
- };
3391
- const options = {
3392
- data: config.data,
3393
- position: "end",
3394
- modal: config.modal ?? true,
3395
- ariaLabel: config.ariaLabel,
3396
- ariaLabelledBy: config.ariaLabel ? void 0 : titleId,
3397
- panelClass: ["bf-side-panel-panel"],
3398
- injector,
3399
- providers,
3400
- enter: slideInFromEnd,
3401
- exit: exitPanel
3402
- };
3403
- let overlayRef;
3404
- if (content instanceof TemplateRef) overlayRef = this.overlays.open(BfSidePanelTemplateHostComponent, options);
3405
- else {
3406
- const componentRef = this.overlays.open(content, options);
3407
- instance = componentRef.componentRef.instance;
3408
- overlayRef = componentRef;
3409
- }
3410
- if (!panelRef) throw new Error("BfSidePanelService: the overlay core did not build the panel providers");
3411
- this.nameUnlabelledPanel(overlayRef.componentRef.location.nativeElement, overlayRef.afterClosed, config, injector);
3412
- return panelRef;
3413
- }
3414
- nameUnlabelledPanel(host, afterClosed, config, injector) {
3415
- const panel = host instanceof HTMLElement ? host.closest(".bf-overlay-panel") : null;
3416
- if (!panel || config.ariaLabel || panel.hasAttribute("aria-labelledby")) return;
3417
- panel.setAttribute("aria-label", injector.get(BF_LABELS).dialog);
3418
- const stop = watchPanelHeading(panel);
3419
- afterClosed.then(stop);
3420
- }
3421
- static ɵfac = i0.ɵɵngDeclareFactory({
3422
- minVersion: "12.0.0",
3423
- version: "22.1.7",
3424
- ngImport: i0,
3425
- type: BfSidePanelService,
3426
- deps: [],
3427
- target: i0.ɵɵFactoryTarget.Injectable
3428
- });
3429
- static ɵprov = i0.ɵɵngDeclareInjectable({
3430
- minVersion: "12.0.0",
3431
- version: "22.1.7",
3432
- ngImport: i0,
3433
- type: BfSidePanelService,
3434
- providedIn: "root"
3435
- });
3436
- };
3437
- i0.ɵɵngDeclareClassMetadata({
3438
- minVersion: "12.0.0",
3439
- version: "22.1.7",
3440
- ngImport: i0,
3441
- type: BfSidePanelService,
3442
- decorators: [{
3443
- type: Injectable,
3444
- args: [{ providedIn: "root" }]
3445
- }]
3446
- });
3447
- var BfTooltipComponent = class BfTooltipComponent {
3448
- text = input("", ...ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []);
3449
- static ɵfac = i0.ɵɵngDeclareFactory({
3450
- minVersion: "12.0.0",
3451
- version: "22.1.7",
3452
- ngImport: i0,
3453
- type: BfTooltipComponent,
3454
- deps: [],
3455
- target: i0.ɵɵFactoryTarget.Component
3456
- });
3457
- static ɵcmp = i0.ɵɵngDeclareComponent({
3458
- minVersion: "17.1.0",
3459
- version: "22.1.7",
3460
- type: BfTooltipComponent,
3461
- isStandalone: true,
3462
- selector: "bf-tooltip",
3463
- inputs: { text: {
3464
- classPropertyName: "text",
3465
- publicName: "text",
3466
- isSignal: true,
3467
- isRequired: false,
3468
- transformFunction: null
3469
- } },
3470
- host: {
3471
- attributes: { "role": "tooltip" },
3472
- classAttribute: "block max-w-xs rounded-field border border-transparent bg-tooltip px-2.5 py-1 text-label-xs text-on-tooltip shadow-raised break-words"
3473
- },
3474
- ngImport: i0,
3475
- template: "{{ text() }}",
3476
- isInline: true
3477
- });
3478
- };
3479
- i0.ɵɵngDeclareClassMetadata({
3480
- minVersion: "12.0.0",
3481
- version: "22.1.7",
3482
- ngImport: i0,
3483
- type: BfTooltipComponent,
3484
- decorators: [{
3485
- type: Component,
3486
- args: [{
3487
- selector: "bf-tooltip",
3488
- host: {
3489
- role: "tooltip",
3490
- class: "block max-w-xs rounded-field border border-transparent bg-tooltip px-2.5 py-1 text-label-xs text-on-tooltip shadow-raised break-words"
3491
- },
3492
- template: "{{ text() }}"
3076
+ template: "{{ text() }}"
3493
3077
  }]
3494
3078
  }],
3495
3079
  propDecorators: { text: [{
@@ -3699,6 +3283,547 @@ i0.ɵɵngDeclareClassMetadata({
3699
3283
  }]
3700
3284
  }
3701
3285
  });
3286
+ const ICON = ɵBF_ICON_BUTTON_CLASSES;
3287
+ const HOST = {
3288
+ shown: "inline-flex",
3289
+ none: "hidden"
3290
+ };
3291
+ var BfSidebarToggleComponent = class BfSidebarToggleComponent {
3292
+ defaults = inject(BF_DEFAULTS);
3293
+ labels = inject(BF_LABELS);
3294
+ host = inject(ɵBF_NAV, { optional: true });
3295
+ nav = this.host?.layout === "sidebar" ? this.host : null;
3296
+ size = input(void 0, ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
3297
+ collapsed = computed(() => this.nav?.collapsed() ?? false, ...ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []);
3298
+ name = computed(() => this.collapsed() ? this.labels.sidebarExpand : this.labels.sidebarCollapse, ...ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []);
3299
+ hostClasses = computed(() => HOST[this.nav ? "shown" : "none"], ...ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []);
3300
+ classes = computed(() => {
3301
+ const size = this.size() ?? this.defaults.controlSize;
3302
+ return [
3303
+ ICON.base,
3304
+ ICON.variant.text,
3305
+ ICON.pressed.text,
3306
+ ICON.size[size],
3307
+ ɵPILL_HIT[size].plain
3308
+ ].filter(Boolean).join(" ");
3309
+ }, ...ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []);
3310
+ toggle() {
3311
+ this.nav?.setCollapsed(!this.collapsed());
3312
+ }
3313
+ static ɵfac = i0.ɵɵngDeclareFactory({
3314
+ minVersion: "12.0.0",
3315
+ version: "22.1.7",
3316
+ ngImport: i0,
3317
+ type: BfSidebarToggleComponent,
3318
+ deps: [],
3319
+ target: i0.ɵɵFactoryTarget.Component
3320
+ });
3321
+ static ɵcmp = i0.ɵɵngDeclareComponent({
3322
+ minVersion: "17.0.0",
3323
+ version: "22.1.7",
3324
+ type: BfSidebarToggleComponent,
3325
+ isStandalone: true,
3326
+ selector: "bf-sidebar-toggle",
3327
+ inputs: { size: {
3328
+ classPropertyName: "size",
3329
+ publicName: "size",
3330
+ isSignal: true,
3331
+ isRequired: false,
3332
+ transformFunction: null
3333
+ } },
3334
+ host: { properties: { "class": "hostClasses()" } },
3335
+ ngImport: i0,
3336
+ template: `
3337
+ @if (nav) {
3338
+ <button
3339
+ type="button"
3340
+ [class]="classes()"
3341
+ [attr.aria-label]="name()"
3342
+ [attr.aria-expanded]="!collapsed()"
3343
+ [attr.aria-controls]="nav.navId"
3344
+ [bfTooltip]="name()"
3345
+ [bfTooltipPlacement]="collapsed() ? 'end' : 'top'"
3346
+ (click)="toggle()"
3347
+ >
3348
+ <!-- display: contents, so the projected icon is the button's own flex item. -->
3349
+ <span [class]="collapsed() ? 'hidden' : 'contents'"
3350
+ ><ng-content select="[bfSlot=collapse-icon]"
3351
+ /></span>
3352
+ <span [class]="collapsed() ? 'contents' : 'hidden'"
3353
+ ><ng-content select="[bfSlot=expand-icon]"
3354
+ /></span>
3355
+ </button>
3356
+ }
3357
+ `,
3358
+ isInline: true,
3359
+ dependencies: [{
3360
+ kind: "directive",
3361
+ type: BfTooltipDirective,
3362
+ selector: "[bfTooltip]",
3363
+ inputs: ["bfTooltip", "bfTooltipPlacement"]
3364
+ }]
3365
+ });
3366
+ };
3367
+ i0.ɵɵngDeclareClassMetadata({
3368
+ minVersion: "12.0.0",
3369
+ version: "22.1.7",
3370
+ ngImport: i0,
3371
+ type: BfSidebarToggleComponent,
3372
+ decorators: [{
3373
+ type: Component,
3374
+ args: [{
3375
+ selector: "bf-sidebar-toggle",
3376
+ imports: [BfTooltipDirective],
3377
+ host: { "[class]": "hostClasses()" },
3378
+ template: `
3379
+ @if (nav) {
3380
+ <button
3381
+ type="button"
3382
+ [class]="classes()"
3383
+ [attr.aria-label]="name()"
3384
+ [attr.aria-expanded]="!collapsed()"
3385
+ [attr.aria-controls]="nav.navId"
3386
+ [bfTooltip]="name()"
3387
+ [bfTooltipPlacement]="collapsed() ? 'end' : 'top'"
3388
+ (click)="toggle()"
3389
+ >
3390
+ <!-- display: contents, so the projected icon is the button's own flex item. -->
3391
+ <span [class]="collapsed() ? 'hidden' : 'contents'"
3392
+ ><ng-content select="[bfSlot=collapse-icon]"
3393
+ /></span>
3394
+ <span [class]="collapsed() ? 'contents' : 'hidden'"
3395
+ ><ng-content select="[bfSlot=expand-icon]"
3396
+ /></span>
3397
+ </button>
3398
+ }
3399
+ `
3400
+ }]
3401
+ }],
3402
+ propDecorators: { size: [{
3403
+ type: i0.Input,
3404
+ args: [{
3405
+ isSignal: true,
3406
+ alias: "size",
3407
+ required: false
3408
+ }]
3409
+ }] }
3410
+ });
3411
+ const BF_SIDE_PANEL_DATA = new InjectionToken("BF_SIDE_PANEL_DATA");
3412
+ const BF_SIDE_PANEL_CONTEXT = new InjectionToken("BF_SIDE_PANEL_CONTEXT");
3413
+ var BfSidePanelRef = class {
3414
+ overlayRef;
3415
+ instance;
3416
+ id;
3417
+ afterClosed;
3418
+ closed;
3419
+ constructor(overlayRef, instance = () => null) {
3420
+ this.overlayRef = overlayRef;
3421
+ this.instance = instance;
3422
+ this.id = overlayRef.id;
3423
+ this.afterClosed = overlayRef.afterClosed;
3424
+ this.closed = overlayRef.closed;
3425
+ }
3426
+ get componentInstance() {
3427
+ return this.instance();
3428
+ }
3429
+ close(result) {
3430
+ this.overlayRef.close(result);
3431
+ }
3432
+ };
3433
+ const HOST_BASE = "relative flex h-full flex-col border-s border-border bg-surface text-text shadow-floating";
3434
+ const WIDTH = {
3435
+ sm: "w-[min(22.5rem,100vw)]",
3436
+ md: "w-[min(30rem,100vw)]",
3437
+ lg: "w-[min(40rem,100vw)]"
3438
+ };
3439
+ var BfSidePanelComponent = class BfSidePanelComponent {
3440
+ labels = inject(BF_LABELS);
3441
+ context = inject(BF_SIDE_PANEL_CONTEXT, { optional: true });
3442
+ ref = inject(BfSidePanelRef, { optional: true });
3443
+ title = input("", ...ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []);
3444
+ closeLabel = input("", ...ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []);
3445
+ overflowing = signal(false, ...ngDevMode ? [{ debugName: "overflowing" }] : /* istanbul ignore next */ []);
3446
+ titleId = this.context?.titleId ?? ɵuniqueId("bf-side-panel-title");
3447
+ closeIcon = X;
3448
+ width = this.context?.width ?? "md";
3449
+ hostClasses = computed(() => `${HOST_BASE} ${WIDTH[this.width]}`, ...ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []);
3450
+ closeName = computed(() => this.closeLabel() || this.labels.close, ...ngDevMode ? [{ debugName: "closeName" }] : /* istanbul ignore next */ []);
3451
+ body = viewChild.required("body", ...ngDevMode ? [{ debugName: "body" }] : /* istanbul ignore next */ []);
3452
+ content = viewChild.required("content", ...ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []);
3453
+ constructor() {
3454
+ let observer = null;
3455
+ afterNextRender(() => {
3456
+ const body = this.body().nativeElement;
3457
+ const measure = () => this.overflowing.set(body.scrollHeight > body.clientHeight);
3458
+ measure();
3459
+ if (typeof ResizeObserver === "function") {
3460
+ observer = new ResizeObserver(measure);
3461
+ observer.observe(body);
3462
+ observer.observe(this.content().nativeElement);
3463
+ }
3464
+ });
3465
+ inject(DestroyRef).onDestroy(() => observer?.disconnect());
3466
+ }
3467
+ close() {
3468
+ this.ref?.close();
3469
+ }
3470
+ static ɵfac = i0.ɵɵngDeclareFactory({
3471
+ minVersion: "12.0.0",
3472
+ version: "22.1.7",
3473
+ ngImport: i0,
3474
+ type: BfSidePanelComponent,
3475
+ deps: [],
3476
+ target: i0.ɵɵFactoryTarget.Component
3477
+ });
3478
+ static ɵcmp = i0.ɵɵngDeclareComponent({
3479
+ minVersion: "17.0.0",
3480
+ version: "22.1.7",
3481
+ type: BfSidePanelComponent,
3482
+ isStandalone: true,
3483
+ selector: "bf-side-panel",
3484
+ inputs: {
3485
+ title: {
3486
+ classPropertyName: "title",
3487
+ publicName: "title",
3488
+ isSignal: true,
3489
+ isRequired: false,
3490
+ transformFunction: null
3491
+ },
3492
+ closeLabel: {
3493
+ classPropertyName: "closeLabel",
3494
+ publicName: "closeLabel",
3495
+ isSignal: true,
3496
+ isRequired: false,
3497
+ transformFunction: null
3498
+ }
3499
+ },
3500
+ host: { properties: {
3501
+ "class": "hostClasses()",
3502
+ "attr.data-bf-side-panel-id": "titleId"
3503
+ } },
3504
+ viewQueries: [{
3505
+ propertyName: "body",
3506
+ first: true,
3507
+ predicate: ["body"],
3508
+ descendants: true,
3509
+ isSignal: true
3510
+ }, {
3511
+ propertyName: "content",
3512
+ first: true,
3513
+ predicate: ["content"],
3514
+ descendants: true,
3515
+ isSignal: true
3516
+ }],
3517
+ ngImport: i0,
3518
+ template: `
3519
+ <div
3520
+ data-side-panel-header
3521
+ class="border-border flex min-h-16 min-w-0 shrink-0 items-center gap-3 border-b py-4 ps-6 pe-14"
3522
+ >
3523
+ @if (title()) {
3524
+ <h2 [id]="titleId" class="text-heading min-w-0 flex-1 wrap-anywhere">{{ title() }}</h2>
3525
+ }
3526
+ <ng-content select="[bfSlot=header]" />
3527
+ </div>
3528
+ <div
3529
+ #body
3530
+ data-side-panel-body
3531
+ class="focus-visible:ring-ring min-h-0 flex-1 overflow-y-auto overscroll-contain px-6 py-4 focus-visible:ring-4 focus-visible:outline-hidden focus-visible:ring-inset"
3532
+ [attr.tabindex]="overflowing() ? 0 : null"
3533
+ [attr.role]="overflowing() && title() ? 'region' : null"
3534
+ [attr.aria-labelledby]="overflowing() && title() ? titleId : null"
3535
+ >
3536
+ <div #content class="flex flex-col gap-4"><ng-content /></div>
3537
+ </div>
3538
+ <!-- A projected wrapper (<div bfSlot="footer">) lays out its buttons like the row itself. -->
3539
+ <div
3540
+ data-side-panel-footer
3541
+ class="border-border flex shrink-0 flex-wrap justify-end gap-2 border-t px-6 py-4 *:flex *:min-w-0 *:flex-wrap *:justify-end *:gap-2 empty:hidden"
3542
+ >
3543
+ <ng-content select="[bfSlot=footer]" />
3544
+ </div>
3545
+ <!-- Last in DOM order so first-tabbable focus lands on the content, not on the ×. -->
3546
+ <bf-icon-button
3547
+ data-side-panel-close
3548
+ class="absolute end-3 top-4"
3549
+ variant="text"
3550
+ size="sm"
3551
+ [label]="closeName()"
3552
+ (clicked)="close()"
3553
+ >
3554
+ <bf-icon [icon]="closeIcon" />
3555
+ </bf-icon-button>
3556
+ `,
3557
+ isInline: true,
3558
+ dependencies: [{
3559
+ kind: "component",
3560
+ type: BfIconButtonComponent,
3561
+ selector: "bf-icon-button, a[bfIconButton]",
3562
+ inputs: [
3563
+ "variant",
3564
+ "size",
3565
+ "type",
3566
+ "disabled",
3567
+ "label"
3568
+ ],
3569
+ outputs: ["clicked"]
3570
+ }, {
3571
+ kind: "component",
3572
+ type: BfIconComponent,
3573
+ selector: "bf-icon",
3574
+ inputs: [
3575
+ "icon",
3576
+ "size",
3577
+ "label",
3578
+ "filled"
3579
+ ]
3580
+ }]
3581
+ });
3582
+ };
3583
+ i0.ɵɵngDeclareClassMetadata({
3584
+ minVersion: "12.0.0",
3585
+ version: "22.1.7",
3586
+ ngImport: i0,
3587
+ type: BfSidePanelComponent,
3588
+ decorators: [{
3589
+ type: Component,
3590
+ args: [{
3591
+ selector: "bf-side-panel",
3592
+ imports: [BfIconButtonComponent, BfIconComponent],
3593
+ host: {
3594
+ "[class]": "hostClasses()",
3595
+ "[attr.data-bf-side-panel-id]": "titleId"
3596
+ },
3597
+ template: `
3598
+ <div
3599
+ data-side-panel-header
3600
+ class="border-border flex min-h-16 min-w-0 shrink-0 items-center gap-3 border-b py-4 ps-6 pe-14"
3601
+ >
3602
+ @if (title()) {
3603
+ <h2 [id]="titleId" class="text-heading min-w-0 flex-1 wrap-anywhere">{{ title() }}</h2>
3604
+ }
3605
+ <ng-content select="[bfSlot=header]" />
3606
+ </div>
3607
+ <div
3608
+ #body
3609
+ data-side-panel-body
3610
+ class="focus-visible:ring-ring min-h-0 flex-1 overflow-y-auto overscroll-contain px-6 py-4 focus-visible:ring-4 focus-visible:outline-hidden focus-visible:ring-inset"
3611
+ [attr.tabindex]="overflowing() ? 0 : null"
3612
+ [attr.role]="overflowing() && title() ? 'region' : null"
3613
+ [attr.aria-labelledby]="overflowing() && title() ? titleId : null"
3614
+ >
3615
+ <div #content class="flex flex-col gap-4"><ng-content /></div>
3616
+ </div>
3617
+ <!-- A projected wrapper (<div bfSlot="footer">) lays out its buttons like the row itself. -->
3618
+ <div
3619
+ data-side-panel-footer
3620
+ class="border-border flex shrink-0 flex-wrap justify-end gap-2 border-t px-6 py-4 *:flex *:min-w-0 *:flex-wrap *:justify-end *:gap-2 empty:hidden"
3621
+ >
3622
+ <ng-content select="[bfSlot=footer]" />
3623
+ </div>
3624
+ <!-- Last in DOM order so first-tabbable focus lands on the content, not on the ×. -->
3625
+ <bf-icon-button
3626
+ data-side-panel-close
3627
+ class="absolute end-3 top-4"
3628
+ variant="text"
3629
+ size="sm"
3630
+ [label]="closeName()"
3631
+ (clicked)="close()"
3632
+ >
3633
+ <bf-icon [icon]="closeIcon" />
3634
+ </bf-icon-button>
3635
+ `
3636
+ }]
3637
+ }],
3638
+ ctorParameters: () => [],
3639
+ propDecorators: {
3640
+ title: [{
3641
+ type: i0.Input,
3642
+ args: [{
3643
+ isSignal: true,
3644
+ alias: "title",
3645
+ required: false
3646
+ }]
3647
+ }],
3648
+ closeLabel: [{
3649
+ type: i0.Input,
3650
+ args: [{
3651
+ isSignal: true,
3652
+ alias: "closeLabel",
3653
+ required: false
3654
+ }]
3655
+ }],
3656
+ body: [{
3657
+ type: i0.ViewChild,
3658
+ args: ["body", { isSignal: true }]
3659
+ }],
3660
+ content: [{
3661
+ type: i0.ViewChild,
3662
+ args: ["content", { isSignal: true }]
3663
+ }]
3664
+ }
3665
+ });
3666
+ const BF_SIDE_PANEL_TEMPLATE = new InjectionToken("BF_SIDE_PANEL_TEMPLATE");
3667
+ var BfSidePanelTemplateHostComponent = class BfSidePanelTemplateHostComponent {
3668
+ view = inject(BF_SIDE_PANEL_TEMPLATE);
3669
+ injector = inject(Injector);
3670
+ static ɵfac = i0.ɵɵngDeclareFactory({
3671
+ minVersion: "12.0.0",
3672
+ version: "22.1.7",
3673
+ ngImport: i0,
3674
+ type: BfSidePanelTemplateHostComponent,
3675
+ deps: [],
3676
+ target: i0.ɵɵFactoryTarget.Component
3677
+ });
3678
+ static ɵcmp = i0.ɵɵngDeclareComponent({
3679
+ minVersion: "14.0.0",
3680
+ version: "22.1.7",
3681
+ type: BfSidePanelTemplateHostComponent,
3682
+ isStandalone: true,
3683
+ selector: "bf-side-panel-template-host",
3684
+ host: { styleAttribute: "display: contents" },
3685
+ ngImport: i0,
3686
+ template: `<ng-container
3687
+ [ngTemplateOutlet]="view.template"
3688
+ [ngTemplateOutletContext]="view.context"
3689
+ [ngTemplateOutletInjector]="injector"
3690
+ />`,
3691
+ isInline: true,
3692
+ dependencies: [{
3693
+ kind: "directive",
3694
+ type: NgTemplateOutlet,
3695
+ selector: "[ngTemplateOutlet]",
3696
+ inputs: [
3697
+ "ngTemplateOutletContext",
3698
+ "ngTemplateOutlet",
3699
+ "ngTemplateOutletInjector"
3700
+ ]
3701
+ }]
3702
+ });
3703
+ };
3704
+ i0.ɵɵngDeclareClassMetadata({
3705
+ minVersion: "12.0.0",
3706
+ version: "22.1.7",
3707
+ ngImport: i0,
3708
+ type: BfSidePanelTemplateHostComponent,
3709
+ decorators: [{
3710
+ type: Component,
3711
+ args: [{
3712
+ selector: "bf-side-panel-template-host",
3713
+ imports: [NgTemplateOutlet],
3714
+ host: { style: "display: contents" },
3715
+ template: `<ng-container
3716
+ [ngTemplateOutlet]="view.template"
3717
+ [ngTemplateOutletContext]="view.context"
3718
+ [ngTemplateOutletInjector]="injector"
3719
+ />`
3720
+ }]
3721
+ }]
3722
+ });
3723
+ function exitPanel(el) {
3724
+ el.setAttribute("data-bf-closing", "");
3725
+ return slideOutToEnd(el);
3726
+ }
3727
+ var BfSidePanelService = class BfSidePanelService {
3728
+ overlays = inject(BfOverlayService);
3729
+ injector = inject(Injector);
3730
+ open(content, config = {}) {
3731
+ const width = config.width ?? "md";
3732
+ const injector = config.injector ?? this.injector;
3733
+ const titleId = ɵuniqueId("bf-side-panel-title");
3734
+ let panelRef = null;
3735
+ let instance = null;
3736
+ const providers = (ref) => {
3737
+ const created = new BfSidePanelRef(ref, () => instance);
3738
+ panelRef = created;
3739
+ const list = [
3740
+ {
3741
+ provide: BfSidePanelRef,
3742
+ useValue: created
3743
+ },
3744
+ {
3745
+ provide: BF_SIDE_PANEL_DATA,
3746
+ useValue: config.data
3747
+ },
3748
+ {
3749
+ provide: BF_SIDE_PANEL_CONTEXT,
3750
+ useValue: {
3751
+ titleId,
3752
+ width
3753
+ }
3754
+ }
3755
+ ];
3756
+ if (content instanceof TemplateRef) {
3757
+ const view = {
3758
+ template: content,
3759
+ context: {
3760
+ $implicit: created,
3761
+ data: config.data
3762
+ }
3763
+ };
3764
+ list.push({
3765
+ provide: BF_SIDE_PANEL_TEMPLATE,
3766
+ useValue: view
3767
+ });
3768
+ }
3769
+ return list;
3770
+ };
3771
+ const options = {
3772
+ data: config.data,
3773
+ position: "end",
3774
+ modal: config.modal ?? true,
3775
+ ariaLabel: config.ariaLabel,
3776
+ ariaLabelledBy: config.ariaLabel ? void 0 : titleId,
3777
+ panelClass: ["bf-side-panel-panel"],
3778
+ injector,
3779
+ providers,
3780
+ enter: slideInFromEnd,
3781
+ exit: exitPanel
3782
+ };
3783
+ let overlayRef;
3784
+ if (content instanceof TemplateRef) overlayRef = this.overlays.open(BfSidePanelTemplateHostComponent, options);
3785
+ else {
3786
+ const componentRef = this.overlays.open(content, options);
3787
+ instance = componentRef.componentRef.instance;
3788
+ overlayRef = componentRef;
3789
+ }
3790
+ if (!panelRef) throw new Error("BfSidePanelService: the overlay core did not build the panel providers");
3791
+ this.nameUnlabelledPanel(overlayRef.componentRef.location.nativeElement, overlayRef.afterClosed, config, injector);
3792
+ return panelRef;
3793
+ }
3794
+ nameUnlabelledPanel(host, afterClosed, config, injector) {
3795
+ const panel = host instanceof HTMLElement ? host.closest(".bf-overlay-panel") : null;
3796
+ if (!panel || config.ariaLabel || panel.hasAttribute("aria-labelledby")) return;
3797
+ panel.setAttribute("aria-label", injector.get(BF_LABELS).dialog);
3798
+ const stop = watchPanelHeading(panel);
3799
+ afterClosed.then(stop);
3800
+ }
3801
+ static ɵfac = i0.ɵɵngDeclareFactory({
3802
+ minVersion: "12.0.0",
3803
+ version: "22.1.7",
3804
+ ngImport: i0,
3805
+ type: BfSidePanelService,
3806
+ deps: [],
3807
+ target: i0.ɵɵFactoryTarget.Injectable
3808
+ });
3809
+ static ɵprov = i0.ɵɵngDeclareInjectable({
3810
+ minVersion: "12.0.0",
3811
+ version: "22.1.7",
3812
+ ngImport: i0,
3813
+ type: BfSidePanelService,
3814
+ providedIn: "root"
3815
+ });
3816
+ };
3817
+ i0.ɵɵngDeclareClassMetadata({
3818
+ minVersion: "12.0.0",
3819
+ version: "22.1.7",
3820
+ ngImport: i0,
3821
+ type: BfSidePanelService,
3822
+ decorators: [{
3823
+ type: Injectable,
3824
+ args: [{ providedIn: "root" }]
3825
+ }]
3826
+ });
3702
3827
  var BfPopoverTriggerDirective = class BfPopoverTriggerDirective {
3703
3828
  overlay = inject(Overlay);
3704
3829
  document = inject(DOCUMENT);
@@ -9073,6 +9198,6 @@ i0.ɵɵngDeclareClassMetadata({
9073
9198
  }]
9074
9199
  }
9075
9200
  });
9076
- export { BF_DESKTOP_TOAST_DEFAULTS, BF_DIALOG_DATA, BF_OVERLAY_DATA, BF_OVERLAY_HOST, BF_SIDE_PANEL_DATA, BfComboboxComponent, BfComponentOverlayRef, BfDateInputComponent, BfDateTimeInputComponent, BfDesktopToastComponent, BfDesktopToastService, BfDialogComponent, BfDialogRef, BfDialogService, BfMenuButtonComponent, BfMenuComponent, BfMenuDividerDirective, BfMenuGroupDirective, BfMenuItemCheckboxDirective, BfMenuItemDirective, BfMenuItemRadioDirective, BfMenuTriggerDirective, BfMultiComboboxComponent, BfOverlayRef, BfOverlayService, BfOverlayStack, BfPopoverComponent, BfPopoverTriggerDirective, BfSidePanelComponent, BfSidePanelRef, BfSidePanelService, BfThemeMenuButtonComponent, BfTimeInputComponent, BfToastRef, BfTooltipComponent, BfTooltipDirective, OVERLAY_DURATION, OVERLAY_EASING, OVERLAY_REDUCED_DURATION, fadeDown, fadeIn, fadeOut, fadeUp, prefersReducedMotion, provideBfDesktopToast, scaleIn, slideDown, slideInFromEnd, slideOutToEnd, slideUp, ɵBfToastQueue, labelPanelByHeading as ɵlabelPanelByHeading, watchPanelHeading as ɵwatchPanelHeading };
9201
+ export { BF_DESKTOP_TOAST_DEFAULTS, BF_DIALOG_DATA, BF_OVERLAY_DATA, BF_OVERLAY_HOST, BF_SIDE_PANEL_DATA, BfComboboxComponent, BfComponentOverlayRef, BfDateInputComponent, BfDateTimeInputComponent, BfDesktopToastComponent, BfDesktopToastService, BfDialogComponent, BfDialogRef, BfDialogService, BfMenuButtonComponent, BfMenuComponent, BfMenuDividerDirective, BfMenuGroupDirective, BfMenuItemCheckboxDirective, BfMenuItemDirective, BfMenuItemRadioDirective, BfMenuTriggerDirective, BfMultiComboboxComponent, BfOverlayRef, BfOverlayService, BfOverlayStack, BfPopoverComponent, BfPopoverTriggerDirective, BfSidePanelComponent, BfSidePanelRef, BfSidePanelService, BfSidebarToggleComponent, BfThemeMenuButtonComponent, BfTimeInputComponent, BfToastRef, BfTooltipComponent, BfTooltipDirective, OVERLAY_DURATION, OVERLAY_EASING, OVERLAY_REDUCED_DURATION, fadeDown, fadeIn, fadeOut, fadeUp, prefersReducedMotion, provideBfDesktopToast, scaleIn, slideDown, slideInFromEnd, slideOutToEnd, slideUp, ɵBfToastQueue, labelPanelByHeading as ɵlabelPanelByHeading, watchPanelHeading as ɵwatchPanelHeading };
9077
9202
 
9078
9203
  //# sourceMappingURL=bitforgehq-ui-overlay.mjs.map