@bitforgehq/ui 0.3.1 → 0.3.3

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 (49) hide show
  1. package/CHANGELOG.md +157 -0
  2. package/README.md +9 -8
  3. package/ai/MANIFEST.index.json +18 -0
  4. package/ai/MANIFEST.json +380 -31
  5. package/ai/REFERENCE.index.json +63 -0
  6. package/ai/REFERENCE.json +265 -7
  7. package/ai/UI_GUIDE.md +59 -33
  8. package/ai/components/app-frame.md +335 -0
  9. package/ai/components/card.md +56 -2
  10. package/ai/components/empty-state.md +99 -6
  11. package/ai/components/header.md +14 -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 +152 -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 +7 -0
  23. package/ai/reference/bf-select-harness.md +4 -0
  24. package/ai/reference/bf-sidebar-state-service.md +21 -0
  25. package/ai/reference/bf-sidebar-toggle-harness.md +32 -0
  26. package/ai/reference/bf-size.md +1 -0
  27. package/ai/reference/bf-stat-appearance.md +33 -0
  28. package/ai/reference/bf-stat-variant.md +1 -1
  29. package/ai/reference/bf-table-harness.md +7 -1
  30. package/ai/reference/bf-table-stack.md +29 -0
  31. package/ai/reference/bf_sidebar_state_storage.md +20 -0
  32. package/ai/reference/provide-bf-labels.md +4 -3
  33. package/ai/reference/provide-bf-sidebar-state.md +20 -0
  34. package/bin/bf-ui.js +433 -3
  35. package/fesm2022/bitforgehq-ui-mobile.mjs +11 -2
  36. package/fesm2022/bitforgehq-ui-mobile.mjs.map +1 -1
  37. package/fesm2022/bitforgehq-ui-overlay.mjs +571 -446
  38. package/fesm2022/bitforgehq-ui-overlay.mjs.map +1 -1
  39. package/fesm2022/bitforgehq-ui-testing.mjs +22 -2
  40. package/fesm2022/bitforgehq-ui-testing.mjs.map +1 -1
  41. package/fesm2022/bitforgehq-ui.mjs +777 -127
  42. package/fesm2022/bitforgehq-ui.mjs.map +1 -1
  43. package/llms-full.txt +1605 -43
  44. package/llms.txt +11 -0
  45. package/package.json +1 -1
  46. package/theme.css +13 -0
  47. package/types/bitforgehq-ui-overlay.d.ts +51 -0
  48. package/types/bitforgehq-ui-testing.d.ts +49 -1
  49. package/types/bitforgehq-ui.d.ts +284 -20
@@ -43,6 +43,10 @@ const BF_DEFAULT_LABELS = {
43
43
  dialog: "Dialog",
44
44
  notifications: "Notifications",
45
45
  tableSelectAll: "Select all rows",
46
+ tableSortBy: "Sort by",
47
+ tableSortNone: "Not sorted",
48
+ tableSortAscending: (column) => `${column}, ascending`,
49
+ tableSortDescending: (column) => `${column}, descending`,
46
50
  theme: "Theme",
47
51
  themeSystem: "System",
48
52
  themeLight: "Light",
@@ -51,6 +55,9 @@ const BF_DEFAULT_LABELS = {
51
55
  breadcrumbExpand: (count) => count === 1 ? "Show 1 more level" : `Show ${count} more levels`,
52
56
  navigation: "Main",
53
57
  navBadge: (count) => `${count} new`,
58
+ sidebarCollapse: "Collapse sidebar",
59
+ sidebarExpand: "Expand sidebar",
60
+ skipToContent: "Skip to main content",
54
61
  pagination: "Pagination",
55
62
  previousPage: "Previous page",
56
63
  nextPage: "Next page",
@@ -138,6 +145,10 @@ function mergeLabels(parent, o) {
138
145
  dialog: o.dialog ?? parent.dialog,
139
146
  notifications: o.notifications ?? parent.notifications,
140
147
  tableSelectAll: o.tableSelectAll ?? parent.tableSelectAll,
148
+ tableSortBy: o.tableSortBy ?? parent.tableSortBy,
149
+ tableSortNone: o.tableSortNone ?? parent.tableSortNone,
150
+ tableSortAscending: o.tableSortAscending ?? parent.tableSortAscending,
151
+ tableSortDescending: o.tableSortDescending ?? parent.tableSortDescending,
141
152
  theme: o.theme ?? parent.theme,
142
153
  themeSystem: o.themeSystem ?? parent.themeSystem,
143
154
  themeLight: o.themeLight ?? parent.themeLight,
@@ -146,6 +157,9 @@ function mergeLabels(parent, o) {
146
157
  breadcrumbExpand: o.breadcrumbExpand ?? parent.breadcrumbExpand,
147
158
  navigation: o.navigation ?? parent.navigation,
148
159
  navBadge: o.navBadge ?? parent.navBadge,
160
+ sidebarCollapse: o.sidebarCollapse ?? parent.sidebarCollapse,
161
+ sidebarExpand: o.sidebarExpand ?? parent.sidebarExpand,
162
+ skipToContent: o.skipToContent ?? parent.skipToContent,
149
163
  pagination: o.pagination ?? parent.pagination,
150
164
  previousPage: o.previousPage ?? parent.previousPage,
151
165
  nextPage: o.nextPage ?? parent.nextPage,
@@ -199,7 +213,7 @@ function mergeLabels(parent, o) {
199
213
  }
200
214
  };
201
215
  }
202
- const STORAGE_KEY = "bf-theme";
216
+ const STORAGE_KEY$1 = "bf-theme";
203
217
  const DARK_QUERY = "(prefers-color-scheme: dark)";
204
218
  function createMemoryColorSchemeStorage() {
205
219
  const values = /* @__PURE__ */ new Map();
@@ -221,17 +235,17 @@ const BF_COLOR_SCHEME_STORAGE = new InjectionToken("BF_COLOR_SCHEME_STORAGE", {
221
235
  providedIn: "root",
222
236
  factory: () => browserStorage() ?? createMemoryColorSchemeStorage()
223
237
  });
224
- function readStored(storage) {
238
+ function readStored$1(storage) {
225
239
  try {
226
- const stored = storage.getItem(STORAGE_KEY);
240
+ const stored = storage.getItem(STORAGE_KEY$1);
227
241
  return stored === "light" || stored === "dark" || stored === "system" ? stored : "system";
228
242
  } catch {
229
243
  return "system";
230
244
  }
231
245
  }
232
- function persist(storage, scheme) {
246
+ function persist$1(storage, scheme) {
233
247
  try {
234
- storage.setItem(STORAGE_KEY, scheme);
248
+ storage.setItem(STORAGE_KEY$1, scheme);
235
249
  } catch {}
236
250
  }
237
251
  var BfColorSchemeService = class BfColorSchemeService {
@@ -239,7 +253,7 @@ var BfColorSchemeService = class BfColorSchemeService {
239
253
  storage = inject(BF_COLOR_SCHEME_STORAGE);
240
254
  injector = inject(Injector);
241
255
  browser = isPlatformBrowser(inject(PLATFORM_ID));
242
- scheme = signal(this.browser ? readStored(this.storage) : "system", ...ngDevMode ? [{ debugName: "scheme" }] : /* istanbul ignore next */ []);
256
+ scheme = signal(this.browser ? readStored$1(this.storage) : "system", ...ngDevMode ? [{ debugName: "scheme" }] : /* istanbul ignore next */ []);
243
257
  prefersDark = signal(false, ...ngDevMode ? [{ debugName: "prefersDark" }] : /* istanbul ignore next */ []);
244
258
  systemDark = this.prefersDark.asReadonly();
245
259
  dark = computed(() => this.scheme() === "system" ? this.prefersDark() : this.scheme() === "dark", ...ngDevMode ? [{ debugName: "dark" }] : /* istanbul ignore next */ []);
@@ -252,10 +266,10 @@ var BfColorSchemeService = class BfColorSchemeService {
252
266
  this.claimed = true;
253
267
  const html = this.document.documentElement;
254
268
  html.classList.toggle("dark", this.dark());
255
- persist(this.storage, this.scheme());
269
+ persist$1(this.storage, this.scheme());
256
270
  effect(() => {
257
271
  html.classList.toggle("dark", this.dark());
258
- persist(this.storage, this.scheme());
272
+ persist$1(this.storage, this.scheme());
259
273
  }, { injector: this.injector });
260
274
  }
261
275
  followSystem() {
@@ -299,6 +313,68 @@ function provideBfColorScheme() {
299
313
  inject(BfColorSchemeService).claimDocument();
300
314
  })]);
301
315
  }
316
+ const STORAGE_KEY = "bf-sidebar-collapsed";
317
+ const BF_SIDEBAR_STATE_STORAGE = new InjectionToken("BF_SIDEBAR_STATE_STORAGE", {
318
+ providedIn: "root",
319
+ factory: () => browserStorage() ?? createMemoryColorSchemeStorage()
320
+ });
321
+ function readStored(storage) {
322
+ try {
323
+ return storage.getItem(STORAGE_KEY) === "true";
324
+ } catch {
325
+ return false;
326
+ }
327
+ }
328
+ function persist(storage, collapsed) {
329
+ try {
330
+ storage.setItem(STORAGE_KEY, String(collapsed));
331
+ } catch {}
332
+ }
333
+ var BfSidebarStateService = class BfSidebarStateService {
334
+ storage = inject(BF_SIDEBAR_STATE_STORAGE);
335
+ injector = inject(Injector);
336
+ browser = isPlatformBrowser(inject(PLATFORM_ID));
337
+ collapsed = signal(this.browser ? readStored(this.storage) : false, ...ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []);
338
+ claimed = false;
339
+ claimStorage() {
340
+ if (this.claimed || !this.browser) return;
341
+ this.claimed = true;
342
+ effect(() => {
343
+ const collapsed = this.collapsed();
344
+ persist(this.storage, collapsed);
345
+ }, { injector: this.injector });
346
+ }
347
+ static ɵfac = i0.ɵɵngDeclareFactory({
348
+ minVersion: "12.0.0",
349
+ version: "22.1.7",
350
+ ngImport: i0,
351
+ type: BfSidebarStateService,
352
+ deps: [],
353
+ target: i0.ɵɵFactoryTarget.Injectable
354
+ });
355
+ static ɵprov = i0.ɵɵngDeclareInjectable({
356
+ minVersion: "12.0.0",
357
+ version: "22.1.7",
358
+ ngImport: i0,
359
+ type: BfSidebarStateService,
360
+ providedIn: "root"
361
+ });
362
+ };
363
+ i0.ɵɵngDeclareClassMetadata({
364
+ minVersion: "12.0.0",
365
+ version: "22.1.7",
366
+ ngImport: i0,
367
+ type: BfSidebarStateService,
368
+ decorators: [{
369
+ type: Injectable,
370
+ args: [{ providedIn: "root" }]
371
+ }]
372
+ });
373
+ function provideBfSidebarState() {
374
+ return makeEnvironmentProviders([provideEnvironmentInitializer(() => {
375
+ inject(BfSidebarStateService).claimStorage();
376
+ })]);
377
+ }
302
378
  function isRecord(value) {
303
379
  return typeof value === "object" && value !== null;
304
380
  }
@@ -527,7 +603,7 @@ const SIZE$5 = {
527
603
  md: "h-10 text-label-sm",
528
604
  lg: "h-12 text-label"
529
605
  };
530
- const PADDING$2 = {
606
+ const PADDING$3 = {
531
607
  sm: "px-3.5",
532
608
  md: "px-4.5",
533
609
  lg: "px-6"
@@ -543,7 +619,7 @@ const BUTTON_CLASSES = {
543
619
  pressed: PRESSED$2.button,
544
620
  current: CURRENT,
545
621
  size: SIZE$5,
546
- padding: PADDING$2,
622
+ padding: PADDING$3,
547
623
  textPadding: TEXT_PADDING
548
624
  };
549
625
  var BfButtonComponent = class BfButtonComponent {
@@ -569,7 +645,7 @@ var BfButtonComponent = class BfButtonComponent {
569
645
  classes = computed(() => {
570
646
  const size = this.resolvedSize();
571
647
  const variant = this.variant();
572
- const padding = variant === "text" || variant === "ghost" ? TEXT_PADDING[size] : PADDING$2[size];
648
+ const padding = variant === "text" || variant === "ghost" ? TEXT_PADDING[size] : PADDING$3[size];
573
649
  const hit = PILL_HIT[size][variant === "outline" ? "bordered" : "plain"];
574
650
  const width = this.fullWidth() ? "w-full" : "";
575
651
  const state = this.loading() && !this.isLink ? "loading" : "idle";
@@ -6641,7 +6717,7 @@ const VARIANT$3 = {
6641
6717
  ink: "bg-text text-bg",
6642
6718
  flat: "bg-surface text-text border-[1.5px] border-border-strong"
6643
6719
  };
6644
- const PADDING$1 = {
6720
+ const PADDING$2 = {
6645
6721
  md: "p-card",
6646
6722
  lg: "p-card-lg"
6647
6723
  };
@@ -6664,7 +6740,7 @@ var BfCardComponent = class BfCardComponent {
6664
6740
  classes = computed(() => [
6665
6741
  BASE$4,
6666
6742
  VARIANT$3[this.variant()],
6667
- PADDING$1[this.padding()],
6743
+ PADDING$2[this.padding()],
6668
6744
  this.interactive() ? INTERACTIVE : ACTION[this.actionState()]
6669
6745
  ].filter(Boolean).join(" "), ...ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []);
6670
6746
  actionState = computed(() => {
@@ -7438,10 +7514,16 @@ var BfEmptyStateComponent = class BfEmptyStateComponent {
7438
7514
  >
7439
7515
  <ng-content select="[bfSlot=icon]" />
7440
7516
  </div>
7441
- @if (headingLevel() === 3) {
7442
- <h3 class="text-heading text-text">{{ title() }}</h3>
7443
- } @else {
7444
- <h2 class="text-heading text-text">{{ title() }}</h2>
7517
+ @switch (headingLevel()) {
7518
+ @case (1) {
7519
+ <h1 class="text-heading text-text">{{ title() }}</h1>
7520
+ }
7521
+ @case (3) {
7522
+ <h3 class="text-heading text-text">{{ title() }}</h3>
7523
+ }
7524
+ @default {
7525
+ <h2 class="text-heading text-text">{{ title() }}</h2>
7526
+ }
7445
7527
  }
7446
7528
  @if (description()) {
7447
7529
  <p class="text-body text-text-muted max-w-sm">{{ description() }}</p>
@@ -7472,10 +7554,16 @@ i0.ɵɵngDeclareClassMetadata({
7472
7554
  >
7473
7555
  <ng-content select="[bfSlot=icon]" />
7474
7556
  </div>
7475
- @if (headingLevel() === 3) {
7476
- <h3 class="text-heading text-text">{{ title() }}</h3>
7477
- } @else {
7478
- <h2 class="text-heading text-text">{{ title() }}</h2>
7557
+ @switch (headingLevel()) {
7558
+ @case (1) {
7559
+ <h1 class="text-heading text-text">{{ title() }}</h1>
7560
+ }
7561
+ @case (3) {
7562
+ <h3 class="text-heading text-text">{{ title() }}</h3>
7563
+ }
7564
+ @default {
7565
+ <h2 class="text-heading text-text">{{ title() }}</h2>
7566
+ }
7479
7567
  }
7480
7568
  @if (description()) {
7481
7569
  <p class="text-body text-text-muted max-w-sm">{{ description() }}</p>
@@ -8966,10 +9054,19 @@ var BfToolbarComponent = class BfToolbarComponent {
8966
9054
  template: `
8967
9055
  <ng-content />
8968
9056
  <ng-content select="[bfSlot=view]" />
8969
- <span role="status" [class]="statusClasses()">{{ status() }}</span>
8970
- <!-- One flex item, so the actions wrap onto the next row together, never one by one. -->
8971
- <div class="ms-auto flex max-w-full flex-wrap items-center gap-2 empty:hidden">
8972
- <ng-content select="[bfSlot=actions]" />
9057
+ <!-- The status and the actions are one flex item that takes the rest of the row: on a narrow
9058
+ row they wrap together, the status at the start and the actions at the inline end, so the
9059
+ actions never sit alone on a row. With no actions the group dissolves (display: contents)
9060
+ and the status is a plain item of the row. -->
9061
+ <div
9062
+ data-end
9063
+ class="flex max-w-full grow flex-wrap items-center gap-2 has-[>div:empty]:contents"
9064
+ >
9065
+ <span role="status" [class]="statusClasses()">{{ status() }}</span>
9066
+ <!-- One flex item, so the actions wrap together, never one by one. -->
9067
+ <div class="ms-auto flex max-w-full flex-wrap items-center gap-2 empty:hidden">
9068
+ <ng-content select="[bfSlot=actions]" />
9069
+ </div>
8973
9070
  </div>
8974
9071
  `,
8975
9072
  isInline: true
@@ -8993,10 +9090,19 @@ i0.ɵɵngDeclareClassMetadata({
8993
9090
  template: `
8994
9091
  <ng-content />
8995
9092
  <ng-content select="[bfSlot=view]" />
8996
- <span role="status" [class]="statusClasses()">{{ status() }}</span>
8997
- <!-- One flex item, so the actions wrap onto the next row together, never one by one. -->
8998
- <div class="ms-auto flex max-w-full flex-wrap items-center gap-2 empty:hidden">
8999
- <ng-content select="[bfSlot=actions]" />
9093
+ <!-- The status and the actions are one flex item that takes the rest of the row: on a narrow
9094
+ row they wrap together, the status at the start and the actions at the inline end, so the
9095
+ actions never sit alone on a row. With no actions the group dissolves (display: contents)
9096
+ and the status is a plain item of the row. -->
9097
+ <div
9098
+ data-end
9099
+ class="flex max-w-full grow flex-wrap items-center gap-2 has-[>div:empty]:contents"
9100
+ >
9101
+ <span role="status" [class]="statusClasses()">{{ status() }}</span>
9102
+ <!-- One flex item, so the actions wrap together, never one by one. -->
9103
+ <div class="ms-auto flex max-w-full flex-wrap items-center gap-2 empty:hidden">
9104
+ <ng-content select="[bfSlot=actions]" />
9105
+ </div>
9000
9106
  </div>
9001
9107
  `
9002
9108
  }]
@@ -9102,10 +9208,15 @@ const HEAD_CELL = {
9102
9208
  lg: "h-12"
9103
9209
  };
9104
9210
  const BODY_CELL = {
9105
- sm: "h-10 py-1 text-label-sm pointer-coarse:h-hit",
9211
+ sm: "h-10 py-1 text-label-sm",
9106
9212
  md: "h-12 py-1 text-body",
9107
9213
  lg: "h-14 py-1 text-body"
9108
9214
  };
9215
+ const BODY_TOUCH = {
9216
+ never: "pointer-coarse:h-hit",
9217
+ narrow: "@min-xl:pointer-coarse:h-hit",
9218
+ coarse: ""
9219
+ };
9109
9220
  const ALIGN = {
9110
9221
  start: "text-start",
9111
9222
  end: "text-end tabular-nums"
@@ -9135,6 +9246,77 @@ const OWN_ARROWS = /* @__PURE__ */ new Set([
9135
9246
  "menu",
9136
9247
  "tab"
9137
9248
  ]);
9249
+ const STACK_HOST = {
9250
+ never: "block",
9251
+ narrow: "block @container",
9252
+ coarse: "block"
9253
+ };
9254
+ const STACK_BAR = {
9255
+ never: "hidden",
9256
+ narrow: "hidden @max-xl:flex",
9257
+ coarse: "hidden pointer-coarse:flex"
9258
+ };
9259
+ const STACK_TABLE = {
9260
+ never: "",
9261
+ narrow: "@max-xl:block",
9262
+ coarse: "pointer-coarse:block"
9263
+ };
9264
+ const STACK_HEAD = {
9265
+ never: "",
9266
+ narrow: "@max-xl:sr-only",
9267
+ coarse: "pointer-coarse:sr-only"
9268
+ };
9269
+ const STACK_ONLY = {
9270
+ never: "hidden",
9271
+ narrow: "hidden @max-xl:inline",
9272
+ coarse: "hidden pointer-coarse:inline"
9273
+ };
9274
+ const STACK_NEVER = {
9275
+ never: "",
9276
+ narrow: "@max-xl:hidden",
9277
+ coarse: "pointer-coarse:hidden"
9278
+ };
9279
+ const STACK_BODY = {
9280
+ never: "",
9281
+ narrow: "@max-xl:flex @max-xl:flex-col @max-xl:gap-2 @max-xl:divide-y-0",
9282
+ coarse: "pointer-coarse:flex pointer-coarse:flex-col pointer-coarse:gap-2 pointer-coarse:divide-y-0"
9283
+ };
9284
+ const STACK_ROW = {
9285
+ never: "",
9286
+ narrow: "@max-xl:grid @max-xl:items-center @max-xl:gap-x-3 @max-xl:rounded-tile @max-xl:px-3 @max-xl:py-2",
9287
+ coarse: "pointer-coarse:grid pointer-coarse:items-center pointer-coarse:gap-x-3 pointer-coarse:rounded-tile pointer-coarse:px-3 pointer-coarse:py-2"
9288
+ };
9289
+ const STACK_ROW_SELECTABLE = {
9290
+ never: "",
9291
+ narrow: "@max-xl:grid-cols-[auto_minmax(0,1fr)]",
9292
+ coarse: "pointer-coarse:grid-cols-[auto_minmax(0,1fr)]"
9293
+ };
9294
+ const STACK_ROW_FILL = {
9295
+ never: "",
9296
+ narrow: "@max-xl:bg-surface-sunken",
9297
+ coarse: "pointer-coarse:bg-surface-sunken"
9298
+ };
9299
+ const STACK_SELECT_CELL = {
9300
+ never: "",
9301
+ narrow: "@max-xl:flex @max-xl:h-auto @max-xl:w-auto @max-xl:p-0",
9302
+ coarse: "pointer-coarse:flex pointer-coarse:h-auto pointer-coarse:w-auto pointer-coarse:p-0"
9303
+ };
9304
+ const STACK_FIRST_CELL = {
9305
+ never: "",
9306
+ narrow: "@max-xl:block @max-xl:h-auto @max-xl:px-0 @max-xl:py-1 @max-xl:text-start @max-xl:font-bold",
9307
+ coarse: "pointer-coarse:block pointer-coarse:h-auto pointer-coarse:px-0 pointer-coarse:py-1 pointer-coarse:text-start pointer-coarse:font-bold"
9308
+ };
9309
+ const STACK_CELL = {
9310
+ never: "",
9311
+ narrow: "@max-xl:col-span-full @max-xl:flex @max-xl:h-auto @max-xl:items-baseline @max-xl:justify-between @max-xl:gap-3 @max-xl:px-0 @max-xl:py-1 @max-xl:text-end @max-xl:before:shrink-0 @max-xl:before:text-start @max-xl:before:text-label-xs @max-xl:before:font-bold @max-xl:before:text-text-muted @max-xl:before:content-data-label",
9312
+ coarse: "pointer-coarse:col-span-full pointer-coarse:flex pointer-coarse:h-auto pointer-coarse:items-baseline pointer-coarse:justify-between pointer-coarse:gap-3 pointer-coarse:px-0 pointer-coarse:py-1 pointer-coarse:text-end pointer-coarse:before:shrink-0 pointer-coarse:before:text-start pointer-coarse:before:text-label-xs pointer-coarse:before:font-bold pointer-coarse:before:text-text-muted pointer-coarse:before:content-data-label"
9313
+ };
9314
+ const SORT_NONE = "";
9315
+ const STACK_EMPTY = {
9316
+ never: "",
9317
+ narrow: "@max-xl:block",
9318
+ coarse: "pointer-coarse:block"
9319
+ };
9138
9320
  var BfTableComponent = class BfTableComponent {
9139
9321
  rows = input.required(...ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []);
9140
9322
  columns = input.required(...ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []);
@@ -9148,11 +9330,13 @@ var BfTableComponent = class BfTableComponent {
9148
9330
  selection = model([], ...ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []);
9149
9331
  selectAllLabel = input("", ...ngDevMode ? [{ debugName: "selectAllLabel" }] : /* istanbul ignore next */ []);
9150
9332
  size = input(void 0, ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
9333
+ stack = input("never", ...ngDevMode ? [{ debugName: "stack" }] : /* istanbul ignore next */ []);
9151
9334
  labels = inject(BF_LABELS);
9152
9335
  defaults = inject(BF_DEFAULTS);
9153
9336
  table = viewChild.required("table", ...ngDevMode ? [{ debugName: "table" }] : /* istanbul ignore next */ []);
9154
9337
  cells = contentChildren(BfTableCellDirective, ...ngDevMode ? [{ debugName: "cells" }] : /* istanbul ignore next */ []);
9155
9338
  id = uniqueId("bf-table");
9339
+ captionId = `${this.id}-caption`;
9156
9340
  resolvedSize = computed(() => this.size() ?? this.defaults.controlSize, ...ngDevMode ? [{ debugName: "resolvedSize" }] : /* istanbul ignore next */ []);
9157
9341
  selectAllName = computed(() => this.selectAllLabel() || this.labels.tableSelectAll, ...ngDevMode ? [{ debugName: "selectAllName" }] : /* istanbul ignore next */ []);
9158
9342
  entries = computed(() => {
@@ -9175,18 +9359,57 @@ var BfTableComponent = class BfTableComponent {
9175
9359
  return !this.allSelected() && this.entries().some((entry) => selected.has(entry.key));
9176
9360
  }, ...ngDevMode ? [{ debugName: "someSelected" }] : /* istanbul ignore next */ []);
9177
9361
  columnCount = computed(() => this.columns().length + (this.selectable() ? 1 : 0), ...ngDevMode ? [{ debugName: "columnCount" }] : /* istanbul ignore next */ []);
9178
- sortButton = SORT_BUTTON;
9362
+ stacks = computed(() => this.stack() !== "never", ...ngDevMode ? [{ debugName: "stacks" }] : /* istanbul ignore next */ []);
9363
+ sortOptions = computed(() => {
9364
+ const sortable = this.columns().filter((column) => column.sortable);
9365
+ if (sortable.length === 0) return [];
9366
+ return [{
9367
+ value: SORT_NONE,
9368
+ label: this.labels.tableSortNone
9369
+ }, ...sortable.flatMap((column) => [{
9370
+ value: `${column.key}:ascending`,
9371
+ label: this.labels.tableSortAscending(column.label)
9372
+ }, {
9373
+ value: `${column.key}:descending`,
9374
+ label: this.labels.tableSortDescending(column.label)
9375
+ }])];
9376
+ }, ...ngDevMode ? [{ debugName: "sortOptions" }] : /* istanbul ignore next */ []);
9377
+ sortValue = computed(() => {
9378
+ const sort = this.sort();
9379
+ return sort ? `${sort.column}:${sort.direction}` : SORT_NONE;
9380
+ }, ...ngDevMode ? [{ debugName: "sortValue" }] : /* istanbul ignore next */ []);
9381
+ hostClasses = computed(() => STACK_HOST[this.stack()], ...ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []);
9382
+ stackBarClasses = computed(() => `${STACK_BAR[this.stack()]} flex-wrap items-end justify-between gap-x-4 gap-y-2 pb-3`, ...ngDevMode ? [{ debugName: "stackBarClasses" }] : /* istanbul ignore next */ []);
9383
+ tableClasses = computed(() => `w-full border-collapse ${STACK_TABLE[this.stack()]}`, ...ngDevMode ? [{ debugName: "tableClasses" }] : /* istanbul ignore next */ []);
9384
+ headClasses = computed(() => STACK_HEAD[this.stack()], ...ngDevMode ? [{ debugName: "headClasses" }] : /* istanbul ignore next */ []);
9385
+ bodyGroupClasses = computed(() => `divide-border divide-y ${STACK_BODY[this.stack()]}`, ...ngDevMode ? [{ debugName: "bodyGroupClasses" }] : /* istanbul ignore next */ []);
9386
+ sortButtonClasses = computed(() => `${SORT_BUTTON} ${STACK_NEVER[this.stack()]}`, ...ngDevMode ? [{ debugName: "sortButtonClasses" }] : /* istanbul ignore next */ []);
9387
+ notStackedClasses = computed(() => STACK_NEVER[this.stack()], ...ngDevMode ? [{ debugName: "notStackedClasses" }] : /* istanbul ignore next */ []);
9388
+ stackedOnlyClasses = computed(() => STACK_ONLY[this.stack()], ...ngDevMode ? [{ debugName: "stackedOnlyClasses" }] : /* istanbul ignore next */ []);
9389
+ stackEmptyClasses = computed(() => STACK_EMPTY[this.stack()], ...ngDevMode ? [{ debugName: "stackEmptyClasses" }] : /* istanbul ignore next */ []);
9179
9390
  selectHeadClasses = computed(() => `${HEAD_BASE} ${HEAD_CELL[this.resolvedSize()]} ${SELECT_CELL}`, ...ngDevMode ? [{ debugName: "selectHeadClasses" }] : /* istanbul ignore next */ []);
9180
- selectBodyClasses = computed(() => `${BODY_BASE} ${BODY_CELL[this.resolvedSize()]} ${SELECT_CELL}`, ...ngDevMode ? [{ debugName: "selectBodyClasses" }] : /* istanbul ignore next */ []);
9181
- headClasses(column) {
9391
+ selectBodyClasses = computed(() => `${BODY_BASE} ${this.bodyHeight()} ${SELECT_CELL} ${STACK_SELECT_CELL[this.stack()]}`, ...ngDevMode ? [{ debugName: "selectBodyClasses" }] : /* istanbul ignore next */ []);
9392
+ bodyHeight = computed(() => {
9393
+ const size = this.resolvedSize();
9394
+ const touch = size === "sm" ? BODY_TOUCH[this.stack()] : "";
9395
+ return touch ? `${BODY_CELL[size]} ${touch}` : BODY_CELL[size];
9396
+ }, ...ngDevMode ? [{ debugName: "bodyHeight" }] : /* istanbul ignore next */ []);
9397
+ headCellClasses(column) {
9182
9398
  return `${HEAD_BASE} ${HEAD_CELL[this.resolvedSize()]} ${ALIGN[column.align ?? "start"]}`;
9183
9399
  }
9184
- bodyClasses(column) {
9185
- return `${BODY_BASE} ${BODY_CELL[this.resolvedSize()]} ${ALIGN[column.align ?? "start"]}`;
9400
+ bodyClasses(column, first) {
9401
+ const stacked = (first ? STACK_FIRST_CELL : STACK_CELL)[this.stack()];
9402
+ return `${BODY_BASE} ${this.bodyHeight()} ${ALIGN[column.align ?? "start"]} ${stacked}`.trim();
9186
9403
  }
9187
9404
  rowClasses(key) {
9188
9405
  const state = this.selectedKeys().has(key) ? "selected" : this.selectable() ? "selectable" : "static";
9189
- return `transition-colors ${ROW[state]}`;
9406
+ const stack = this.stack();
9407
+ const tile = [
9408
+ STACK_ROW[stack],
9409
+ this.selectable() ? STACK_ROW_SELECTABLE[stack] : "",
9410
+ state === "selected" ? "" : STACK_ROW_FILL[stack]
9411
+ ].filter(Boolean).join(" ");
9412
+ return `transition-colors ${ROW[state]} ${tile}`.trim();
9190
9413
  }
9191
9414
  arrowClasses(key) {
9192
9415
  const sort = this.sort();
@@ -9211,6 +9434,18 @@ var BfTableComponent = class BfTableComponent {
9211
9434
  direction
9212
9435
  });
9213
9436
  }
9437
+ sortFromOption(value) {
9438
+ if (value === SORT_NONE) {
9439
+ this.sort.set(null);
9440
+ return;
9441
+ }
9442
+ const at = value.lastIndexOf(":");
9443
+ const direction = value.slice(at + 1);
9444
+ if (at > 0 && (direction === "ascending" || direction === "descending")) this.sort.set({
9445
+ column: value.slice(0, at),
9446
+ direction
9447
+ });
9448
+ }
9214
9449
  selectAll(selected) {
9215
9450
  const keys = this.entries().map((entry) => entry.key);
9216
9451
  const shown = new Set(keys);
@@ -9238,7 +9473,7 @@ var BfTableComponent = class BfTableComponent {
9238
9473
  for (let i = rows.indexOf(row) + step; i >= 0 && i < rows.length; i += step) {
9239
9474
  const controls = [...rows[i]?.cells[cell.cellIndex]?.querySelectorAll(FOCUSABLE) ?? []];
9240
9475
  const next = controls[Math.min(position, controls.length - 1)];
9241
- if (next instanceof HTMLElement) {
9476
+ if (next instanceof HTMLElement && next.checkVisibility?.() !== false) {
9242
9477
  event.preventDefault();
9243
9478
  next.focus();
9244
9479
  return;
@@ -9322,6 +9557,13 @@ var BfTableComponent = class BfTableComponent {
9322
9557
  isSignal: true,
9323
9558
  isRequired: false,
9324
9559
  transformFunction: null
9560
+ },
9561
+ stack: {
9562
+ classPropertyName: "stack",
9563
+ publicName: "stack",
9564
+ isSignal: true,
9565
+ isRequired: false,
9566
+ transformFunction: null
9325
9567
  }
9326
9568
  },
9327
9569
  outputs: {
@@ -9330,7 +9572,7 @@ var BfTableComponent = class BfTableComponent {
9330
9572
  },
9331
9573
  host: {
9332
9574
  listeners: { "keydown": "onKeydown($event)" },
9333
- classAttribute: "block"
9575
+ properties: { "class": "hostClasses()" }
9334
9576
  },
9335
9577
  queries: [{
9336
9578
  propertyName: "cells",
@@ -9346,20 +9588,53 @@ var BfTableComponent = class BfTableComponent {
9346
9588
  }],
9347
9589
  ngImport: i0,
9348
9590
  template: `
9591
+ @if (stacks() && (selectable() || sortOptions().length > 0)) {
9592
+ <div data-bf-table-stack-bar [class]="stackBarClasses()">
9593
+ @if (selectable()) {
9594
+ <bf-checkbox
9595
+ [size]="resolvedSize()"
9596
+ [label]="selectAllName()"
9597
+ [checked]="allSelected()"
9598
+ [indeterminate]="someSelected()"
9599
+ [disabled]="entries().length === 0"
9600
+ (changed)="selectAll($event)"
9601
+ />
9602
+ }
9603
+ @if (sortOptions().length > 0) {
9604
+ <bf-select
9605
+ class="min-w-0 flex-1 basis-36"
9606
+ [label]="labels.tableSortBy"
9607
+ [options]="sortOptions()"
9608
+ [value]="sortValue()"
9609
+ (changed)="sortFromOption($event)"
9610
+ />
9611
+ }
9612
+ </div>
9613
+ }
9349
9614
  <div data-bf-table-scroller class="max-w-full overflow-x-auto">
9350
- <table #table class="w-full border-collapse">
9615
+ <table
9616
+ #table
9617
+ [attr.role]="stacks() ? 'table' : null"
9618
+ [attr.aria-labelledby]="stacks() && label() ? captionId : null"
9619
+ [class]="tableClasses()"
9620
+ >
9351
9621
  @if (label()) {
9352
- <caption class="sr-only">
9622
+ <caption class="sr-only" [attr.id]="stacks() ? captionId : null">
9353
9623
  {{
9354
9624
  label()
9355
9625
  }}
9356
9626
  </caption>
9357
9627
  }
9358
- <thead>
9359
- <tr class="border-border border-b">
9628
+ <thead [attr.role]="stacks() ? 'rowgroup' : null" [class]="headClasses()">
9629
+ <tr class="border-border border-b" [attr.role]="stacks() ? 'row' : null">
9360
9630
  @if (selectable()) {
9361
- <th scope="col" [class]="selectHeadClasses()">
9631
+ <th
9632
+ scope="col"
9633
+ [attr.role]="stacks() ? 'columnheader' : null"
9634
+ [class]="selectHeadClasses()"
9635
+ >
9362
9636
  <bf-checkbox
9637
+ [class]="notStackedClasses()"
9363
9638
  [size]="resolvedSize()"
9364
9639
  [checked]="allSelected()"
9365
9640
  [indeterminate]="someSelected()"
@@ -9372,15 +9647,21 @@ var BfTableComponent = class BfTableComponent {
9372
9647
  @for (column of columns(); track column.key) {
9373
9648
  <th
9374
9649
  scope="col"
9650
+ [attr.role]="stacks() ? 'columnheader' : null"
9375
9651
  [attr.data-bf-column]="column.key"
9376
9652
  [attr.aria-sort]="ariaSort(column.key)"
9377
- [class]="headClasses(column)"
9653
+ [class]="headCellClasses(column)"
9378
9654
  >
9379
9655
  @if (column.sortable) {
9380
- <button type="button" [class]="sortButton" (click)="sortBy(column.key)">
9656
+ <button type="button" [class]="sortButtonClasses()" (click)="sortBy(column.key)">
9381
9657
  {{ column.label }}
9382
9658
  <span aria-hidden="true" [class]="arrowClasses(column.key)"></span>
9383
9659
  </button>
9660
+ @if (stacks()) {
9661
+ <span data-bf-stacked-label [class]="stackedOnlyClasses()">{{
9662
+ column.label
9663
+ }}</span>
9664
+ }
9384
9665
  } @else {
9385
9666
  {{ column.label }}
9386
9667
  }
@@ -9388,11 +9669,15 @@ var BfTableComponent = class BfTableComponent {
9388
9669
  }
9389
9670
  </tr>
9390
9671
  </thead>
9391
- <tbody class="divide-border divide-y">
9672
+ <tbody [attr.role]="stacks() ? 'rowgroup' : null" [class]="bodyGroupClasses()">
9392
9673
  @for (entry of entries(); track entry.key) {
9393
- <tr data-bf-table-row [class]="rowClasses(entry.key)">
9674
+ <tr
9675
+ data-bf-table-row
9676
+ [attr.role]="stacks() ? 'row' : null"
9677
+ [class]="rowClasses(entry.key)"
9678
+ >
9394
9679
  @if (selectable()) {
9395
- <td [class]="selectBodyClasses()">
9680
+ <td [attr.role]="stacks() ? 'cell' : null" [class]="selectBodyClasses()">
9396
9681
  <bf-checkbox
9397
9682
  [size]="resolvedSize()"
9398
9683
  [checked]="selectedKeys().has(entry.key)"
@@ -9404,8 +9689,10 @@ var BfTableComponent = class BfTableComponent {
9404
9689
  @for (column of columns(); track column.key; let first = $first) {
9405
9690
  <td
9406
9691
  data-bf-cell
9692
+ [attr.role]="stacks() ? 'cell' : null"
9407
9693
  [attr.id]="first ? cellId(entry.index) : null"
9408
- [class]="bodyClasses(column)"
9694
+ [attr.data-label]="stacks() && !first ? column.label : null"
9695
+ [class]="bodyClasses(column, first)"
9409
9696
  >
9410
9697
  @if (templates().get(column.key); as template) {
9411
9698
  <ng-container
@@ -9421,8 +9708,18 @@ var BfTableComponent = class BfTableComponent {
9421
9708
  }
9422
9709
  </tr>
9423
9710
  } @empty {
9424
- <tr data-bf-table-empty>
9425
- <td [attr.colspan]="columnCount()"><ng-content select="[bfSlot=empty]" /></td>
9711
+ <tr
9712
+ data-bf-table-empty
9713
+ [attr.role]="stacks() ? 'row' : null"
9714
+ [class]="stackEmptyClasses()"
9715
+ >
9716
+ <td
9717
+ [attr.role]="stacks() ? 'cell' : null"
9718
+ [attr.colspan]="columnCount()"
9719
+ [class]="stackEmptyClasses()"
9720
+ >
9721
+ <ng-content select="[bfSlot=empty]" />
9722
+ </td>
9426
9723
  </tr>
9427
9724
  }
9428
9725
  </tbody>
@@ -9430,43 +9727,78 @@ var BfTableComponent = class BfTableComponent {
9430
9727
  </div>
9431
9728
  `,
9432
9729
  isInline: true,
9433
- dependencies: [{
9434
- kind: "directive",
9435
- type: NgTemplateOutlet,
9436
- selector: "[ngTemplateOutlet]",
9437
- inputs: [
9438
- "ngTemplateOutletContext",
9439
- "ngTemplateOutlet",
9440
- "ngTemplateOutletInjector"
9441
- ]
9442
- }, {
9443
- kind: "component",
9444
- type: BfCheckboxComponent,
9445
- selector: "bf-checkbox",
9446
- inputs: [
9447
- "checked",
9448
- "label",
9449
- "ariaLabel",
9450
- "ariaLabelledby",
9451
- "size",
9452
- "indeterminate",
9453
- "disabled",
9454
- "readonly",
9455
- "required",
9456
- "invalid",
9457
- "touched",
9458
- "errors",
9459
- "errorMessage",
9460
- "name",
9461
- "id"
9462
- ],
9463
- outputs: [
9464
- "checkedChange",
9465
- "indeterminateChange",
9466
- "changed",
9467
- "touch"
9468
- ]
9469
- }]
9730
+ dependencies: [
9731
+ {
9732
+ kind: "directive",
9733
+ type: NgTemplateOutlet,
9734
+ selector: "[ngTemplateOutlet]",
9735
+ inputs: [
9736
+ "ngTemplateOutletContext",
9737
+ "ngTemplateOutlet",
9738
+ "ngTemplateOutletInjector"
9739
+ ]
9740
+ },
9741
+ {
9742
+ kind: "component",
9743
+ type: BfCheckboxComponent,
9744
+ selector: "bf-checkbox",
9745
+ inputs: [
9746
+ "checked",
9747
+ "label",
9748
+ "ariaLabel",
9749
+ "ariaLabelledby",
9750
+ "size",
9751
+ "indeterminate",
9752
+ "disabled",
9753
+ "readonly",
9754
+ "required",
9755
+ "invalid",
9756
+ "touched",
9757
+ "errors",
9758
+ "errorMessage",
9759
+ "name",
9760
+ "id"
9761
+ ],
9762
+ outputs: [
9763
+ "checkedChange",
9764
+ "indeterminateChange",
9765
+ "changed",
9766
+ "touch"
9767
+ ]
9768
+ },
9769
+ {
9770
+ kind: "component",
9771
+ type: BfSelectComponent,
9772
+ selector: "bf-select",
9773
+ inputs: [
9774
+ "value",
9775
+ "options",
9776
+ "compareWith",
9777
+ "size",
9778
+ "label",
9779
+ "ariaLabel",
9780
+ "ariaLabelledby",
9781
+ "placeholder",
9782
+ "helpText",
9783
+ "errorMessage",
9784
+ "disabled",
9785
+ "readonly",
9786
+ "required",
9787
+ "invalid",
9788
+ "touched",
9789
+ "errors",
9790
+ "name",
9791
+ "id"
9792
+ ],
9793
+ outputs: [
9794
+ "valueChange",
9795
+ "changed",
9796
+ "focused",
9797
+ "blurred",
9798
+ "touch"
9799
+ ]
9800
+ }
9801
+ ]
9470
9802
  });
9471
9803
  };
9472
9804
  i0.ɵɵngDeclareClassMetadata({
@@ -9479,25 +9811,62 @@ i0.ɵɵngDeclareClassMetadata({
9479
9811
  args: [{
9480
9812
  selector: "bf-table",
9481
9813
  host: {
9482
- class: "block",
9814
+ "[class]": "hostClasses()",
9483
9815
  "(keydown)": "onKeydown($event)"
9484
9816
  },
9485
- imports: [NgTemplateOutlet, BfCheckboxComponent],
9817
+ imports: [
9818
+ NgTemplateOutlet,
9819
+ BfCheckboxComponent,
9820
+ BfSelectComponent
9821
+ ],
9486
9822
  template: `
9823
+ @if (stacks() && (selectable() || sortOptions().length > 0)) {
9824
+ <div data-bf-table-stack-bar [class]="stackBarClasses()">
9825
+ @if (selectable()) {
9826
+ <bf-checkbox
9827
+ [size]="resolvedSize()"
9828
+ [label]="selectAllName()"
9829
+ [checked]="allSelected()"
9830
+ [indeterminate]="someSelected()"
9831
+ [disabled]="entries().length === 0"
9832
+ (changed)="selectAll($event)"
9833
+ />
9834
+ }
9835
+ @if (sortOptions().length > 0) {
9836
+ <bf-select
9837
+ class="min-w-0 flex-1 basis-36"
9838
+ [label]="labels.tableSortBy"
9839
+ [options]="sortOptions()"
9840
+ [value]="sortValue()"
9841
+ (changed)="sortFromOption($event)"
9842
+ />
9843
+ }
9844
+ </div>
9845
+ }
9487
9846
  <div data-bf-table-scroller class="max-w-full overflow-x-auto">
9488
- <table #table class="w-full border-collapse">
9847
+ <table
9848
+ #table
9849
+ [attr.role]="stacks() ? 'table' : null"
9850
+ [attr.aria-labelledby]="stacks() && label() ? captionId : null"
9851
+ [class]="tableClasses()"
9852
+ >
9489
9853
  @if (label()) {
9490
- <caption class="sr-only">
9854
+ <caption class="sr-only" [attr.id]="stacks() ? captionId : null">
9491
9855
  {{
9492
9856
  label()
9493
9857
  }}
9494
9858
  </caption>
9495
9859
  }
9496
- <thead>
9497
- <tr class="border-border border-b">
9860
+ <thead [attr.role]="stacks() ? 'rowgroup' : null" [class]="headClasses()">
9861
+ <tr class="border-border border-b" [attr.role]="stacks() ? 'row' : null">
9498
9862
  @if (selectable()) {
9499
- <th scope="col" [class]="selectHeadClasses()">
9863
+ <th
9864
+ scope="col"
9865
+ [attr.role]="stacks() ? 'columnheader' : null"
9866
+ [class]="selectHeadClasses()"
9867
+ >
9500
9868
  <bf-checkbox
9869
+ [class]="notStackedClasses()"
9501
9870
  [size]="resolvedSize()"
9502
9871
  [checked]="allSelected()"
9503
9872
  [indeterminate]="someSelected()"
@@ -9510,15 +9879,21 @@ i0.ɵɵngDeclareClassMetadata({
9510
9879
  @for (column of columns(); track column.key) {
9511
9880
  <th
9512
9881
  scope="col"
9882
+ [attr.role]="stacks() ? 'columnheader' : null"
9513
9883
  [attr.data-bf-column]="column.key"
9514
9884
  [attr.aria-sort]="ariaSort(column.key)"
9515
- [class]="headClasses(column)"
9885
+ [class]="headCellClasses(column)"
9516
9886
  >
9517
9887
  @if (column.sortable) {
9518
- <button type="button" [class]="sortButton" (click)="sortBy(column.key)">
9888
+ <button type="button" [class]="sortButtonClasses()" (click)="sortBy(column.key)">
9519
9889
  {{ column.label }}
9520
9890
  <span aria-hidden="true" [class]="arrowClasses(column.key)"></span>
9521
9891
  </button>
9892
+ @if (stacks()) {
9893
+ <span data-bf-stacked-label [class]="stackedOnlyClasses()">{{
9894
+ column.label
9895
+ }}</span>
9896
+ }
9522
9897
  } @else {
9523
9898
  {{ column.label }}
9524
9899
  }
@@ -9526,11 +9901,15 @@ i0.ɵɵngDeclareClassMetadata({
9526
9901
  }
9527
9902
  </tr>
9528
9903
  </thead>
9529
- <tbody class="divide-border divide-y">
9904
+ <tbody [attr.role]="stacks() ? 'rowgroup' : null" [class]="bodyGroupClasses()">
9530
9905
  @for (entry of entries(); track entry.key) {
9531
- <tr data-bf-table-row [class]="rowClasses(entry.key)">
9906
+ <tr
9907
+ data-bf-table-row
9908
+ [attr.role]="stacks() ? 'row' : null"
9909
+ [class]="rowClasses(entry.key)"
9910
+ >
9532
9911
  @if (selectable()) {
9533
- <td [class]="selectBodyClasses()">
9912
+ <td [attr.role]="stacks() ? 'cell' : null" [class]="selectBodyClasses()">
9534
9913
  <bf-checkbox
9535
9914
  [size]="resolvedSize()"
9536
9915
  [checked]="selectedKeys().has(entry.key)"
@@ -9542,8 +9921,10 @@ i0.ɵɵngDeclareClassMetadata({
9542
9921
  @for (column of columns(); track column.key; let first = $first) {
9543
9922
  <td
9544
9923
  data-bf-cell
9924
+ [attr.role]="stacks() ? 'cell' : null"
9545
9925
  [attr.id]="first ? cellId(entry.index) : null"
9546
- [class]="bodyClasses(column)"
9926
+ [attr.data-label]="stacks() && !first ? column.label : null"
9927
+ [class]="bodyClasses(column, first)"
9547
9928
  >
9548
9929
  @if (templates().get(column.key); as template) {
9549
9930
  <ng-container
@@ -9559,8 +9940,18 @@ i0.ɵɵngDeclareClassMetadata({
9559
9940
  }
9560
9941
  </tr>
9561
9942
  } @empty {
9562
- <tr data-bf-table-empty>
9563
- <td [attr.colspan]="columnCount()"><ng-content select="[bfSlot=empty]" /></td>
9943
+ <tr
9944
+ data-bf-table-empty
9945
+ [attr.role]="stacks() ? 'row' : null"
9946
+ [class]="stackEmptyClasses()"
9947
+ >
9948
+ <td
9949
+ [attr.role]="stacks() ? 'cell' : null"
9950
+ [attr.colspan]="columnCount()"
9951
+ [class]="stackEmptyClasses()"
9952
+ >
9953
+ <ng-content select="[bfSlot=empty]" />
9954
+ </td>
9564
9955
  </tr>
9565
9956
  }
9566
9957
  </tbody>
@@ -9648,6 +10039,14 @@ i0.ɵɵngDeclareClassMetadata({
9648
10039
  required: false
9649
10040
  }]
9650
10041
  }],
10042
+ stack: [{
10043
+ type: i0.Input,
10044
+ args: [{
10045
+ isSignal: true,
10046
+ alias: "stack",
10047
+ required: false
10048
+ }]
10049
+ }],
9651
10050
  table: [{
9652
10051
  type: i0.ViewChild,
9653
10052
  args: ["table", { isSignal: true }]
@@ -9789,7 +10188,14 @@ i0.ɵɵngDeclareClassMetadata({
9789
10188
  const BASE$1 = "flex h-full items-start gap-3 text-start";
9790
10189
  const VARIANT = {
9791
10190
  plain: "",
9792
- card: "rounded-card bg-surface p-card border-[1.5px] border-border-strong"
10191
+ card: "rounded-card bg-surface p-card border-[1.5px] border-border-strong",
10192
+ tile: "rounded-card bg-surface-sunken p-card"
10193
+ };
10194
+ const ICON_TILE = "rounded-tile text-text-muted flex size-10 shrink-0 items-center justify-center empty:hidden";
10195
+ const ICON_TILE_SURFACE = {
10196
+ plain: "bg-surface-sunken",
10197
+ card: "bg-surface-sunken",
10198
+ tile: "bg-surface"
9793
10199
  };
9794
10200
  const DELTA_BASE = "inline-flex items-center gap-1 rounded-control px-2 py-1 text-micro font-bold leading-none tabular-nums";
9795
10201
  const DELTA_TONE = {
@@ -9811,6 +10217,7 @@ var BfStatComponent = class BfStatComponent {
9811
10217
  trendIntent = input("positive", ...ngDevMode ? [{ debugName: "trendIntent" }] : /* istanbul ignore next */ []);
9812
10218
  labels = inject(BF_LABELS);
9813
10219
  classes = computed(() => [BASE$1, VARIANT[this.variant()]].filter(Boolean).join(" "), ...ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []);
10220
+ iconTileClasses = computed(() => `${ICON_TILE} ${ICON_TILE_SURFACE[this.variant()]}`, ...ngDevMode ? [{ debugName: "iconTileClasses" }] : /* istanbul ignore next */ []);
9814
10221
  deltaClasses = computed(() => {
9815
10222
  const trend = this.trend();
9816
10223
  const tone = trend === void 0 || trend === "flat" ? "neutral" : trend === "up" === (this.trendIntent() === "positive") ? "good" : "bad";
@@ -9891,11 +10298,7 @@ var BfStatComponent = class BfStatComponent {
9891
10298
  ngImport: i0,
9892
10299
  template: `
9893
10300
  <div [class]="classes()">
9894
- <span
9895
- data-tile
9896
- class="rounded-tile bg-surface-sunken text-text-muted flex size-10 shrink-0 items-center justify-center empty:hidden"
9897
- ><ng-content select="[bfSlot=icon]"
9898
- /></span>
10301
+ <span data-tile [class]="iconTileClasses()"><ng-content select="[bfSlot=icon]" /></span>
9899
10302
  <dl class="flex min-w-0 flex-col gap-1">
9900
10303
  <dt class="text-caption text-text-muted">{{ label() }}</dt>
9901
10304
  <dd
@@ -9931,11 +10334,7 @@ i0.ɵɵngDeclareClassMetadata({
9931
10334
  host: { class: "block" },
9932
10335
  template: `
9933
10336
  <div [class]="classes()">
9934
- <span
9935
- data-tile
9936
- class="rounded-tile bg-surface-sunken text-text-muted flex size-10 shrink-0 items-center justify-center empty:hidden"
9937
- ><ng-content select="[bfSlot=icon]"
9938
- /></span>
10337
+ <span data-tile [class]="iconTileClasses()"><ng-content select="[bfSlot=icon]" /></span>
9939
10338
  <dl class="flex min-w-0 flex-col gap-1">
9940
10339
  <dt class="text-caption text-text-muted">{{ label() }}</dt>
9941
10340
  <dd
@@ -10303,6 +10702,7 @@ var BfSidebarComponent = class BfSidebarComponent {
10303
10702
  label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
10304
10703
  collapsed = model(false, ...ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []);
10305
10704
  labels = inject(BF_LABELS);
10705
+ navId = uniqueId("bf-sidebar");
10306
10706
  name = computed(() => this.label() || this.labels.navigation, ...ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []);
10307
10707
  width = computed(() => this.collapsed() ? "collapsed" : "expanded", ...ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []);
10308
10708
  hostClasses = computed(() => HOST$2[this.width()], ...ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []);
@@ -10344,14 +10744,20 @@ var BfSidebarComponent = class BfSidebarComponent {
10344
10744
  } },
10345
10745
  providers: [{
10346
10746
  provide: BF_NAV,
10347
- useFactory: () => ({
10348
- layout: "sidebar",
10349
- collapsed: inject(BfSidebarComponent).collapsed
10350
- })
10747
+ useFactory: () => {
10748
+ const sidebar = inject(BfSidebarComponent);
10749
+ return {
10750
+ layout: "sidebar",
10751
+ collapsed: sidebar.collapsed,
10752
+ navId: sidebar.navId,
10753
+ setCollapsed: (collapsed) => sidebar.collapsed.set(collapsed)
10754
+ };
10755
+ }
10351
10756
  }],
10352
10757
  ngImport: i0,
10353
10758
  template: `
10354
10759
  <nav
10760
+ [id]="navId"
10355
10761
  [attr.aria-label]="name()"
10356
10762
  class="border-border bg-surface flex min-h-0 flex-1 flex-col gap-6 border-e p-3"
10357
10763
  >
@@ -10387,13 +10793,19 @@ i0.ɵɵngDeclareClassMetadata({
10387
10793
  },
10388
10794
  providers: [{
10389
10795
  provide: BF_NAV,
10390
- useFactory: () => ({
10391
- layout: "sidebar",
10392
- collapsed: inject(BfSidebarComponent).collapsed
10393
- })
10796
+ useFactory: () => {
10797
+ const sidebar = inject(BfSidebarComponent);
10798
+ return {
10799
+ layout: "sidebar",
10800
+ collapsed: sidebar.collapsed,
10801
+ navId: sidebar.navId,
10802
+ setCollapsed: (collapsed) => sidebar.collapsed.set(collapsed)
10803
+ };
10804
+ }
10394
10805
  }],
10395
10806
  template: `
10396
10807
  <nav
10808
+ [id]="navId"
10397
10809
  [attr.aria-label]="name()"
10398
10810
  class="border-border bg-surface flex min-h-0 flex-1 flex-col gap-6 border-e p-3"
10399
10811
  >
@@ -10465,7 +10877,9 @@ var BfTopNavComponent = class BfTopNavComponent {
10465
10877
  provide: BF_NAV,
10466
10878
  useFactory: () => ({
10467
10879
  layout: "top",
10468
- collapsed: signal(false).asReadonly()
10880
+ collapsed: signal(false).asReadonly(),
10881
+ navId: null,
10882
+ setCollapsed: () => void 0
10469
10883
  })
10470
10884
  }],
10471
10885
  ngImport: i0,
@@ -10491,7 +10905,9 @@ i0.ɵɵngDeclareClassMetadata({
10491
10905
  provide: BF_NAV,
10492
10906
  useFactory: () => ({
10493
10907
  layout: "top",
10494
- collapsed: signal(false).asReadonly()
10908
+ collapsed: signal(false).asReadonly(),
10909
+ navId: null,
10910
+ setCollapsed: () => void 0
10495
10911
  })
10496
10912
  }],
10497
10913
  template: `
@@ -10596,7 +11012,7 @@ const HEIGHT = {
10596
11012
  md: "min-h-10 gap-3 text-label-sm pointer-coarse:min-h-hit",
10597
11013
  lg: "min-h-12 gap-3 text-label pointer-coarse:min-h-hit"
10598
11014
  };
10599
- const PADDING = {
11015
+ const PADDING$1 = {
10600
11016
  sm: "px-3",
10601
11017
  md: "px-3",
10602
11018
  lg: "px-4"
@@ -10638,7 +11054,7 @@ var BfNavItemComponent = class BfNavItemComponent {
10638
11054
  return [
10639
11055
  BASE,
10640
11056
  HEIGHT[size],
10641
- form === "collapsed" ? SQUARE[size] : PADDING[size],
11057
+ form === "collapsed" ? SQUARE[size] : PADDING$1[size],
10642
11058
  FORM[form]
10643
11059
  ].join(" ");
10644
11060
  }, ...ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []);
@@ -10768,6 +11184,240 @@ i0.ɵɵngDeclareClassMetadata({
10768
11184
  }]
10769
11185
  }
10770
11186
  });
11187
+ const SIDEBAR = {
11188
+ md: "hidden md:flex",
11189
+ lg: "hidden lg:flex"
11190
+ };
11191
+ const HEADER = {
11192
+ md: "flex md:hidden",
11193
+ lg: "flex lg:hidden"
11194
+ };
11195
+ const PADDING = {
11196
+ md: "p-4 md:p-8",
11197
+ lg: "p-4 lg:p-8"
11198
+ };
11199
+ const WIDTH = {
11200
+ md: "max-w-3xl",
11201
+ lg: "max-w-5xl",
11202
+ xl: "max-w-7xl",
11203
+ full: "max-w-none"
11204
+ };
11205
+ var BfAppFrameComponent = class BfAppFrameComponent {
11206
+ breakpoint = input("md", ...ngDevMode ? [{ debugName: "breakpoint" }] : /* istanbul ignore next */ []);
11207
+ contentWidth = input("xl", ...ngDevMode ? [{ debugName: "contentWidth" }] : /* istanbul ignore next */ []);
11208
+ mainId = input(uniqueId("bf-app-frame-main"), ...ngDevMode ? [{ debugName: "mainId" }] : /* istanbul ignore next */ []);
11209
+ labels = inject(BF_LABELS);
11210
+ host = inject(ElementRef);
11211
+ main = viewChild.required("main", ...ngDevMode ? [{ debugName: "main" }] : /* istanbul ignore next */ []);
11212
+ nested = signal(false, ...ngDevMode ? [{ debugName: "nested" }] : /* istanbul ignore next */ []);
11213
+ sidebarClasses = computed(() => SIDEBAR[this.breakpoint()], ...ngDevMode ? [{ debugName: "sidebarClasses" }] : /* istanbul ignore next */ []);
11214
+ headerClasses = computed(() => HEADER[this.breakpoint()], ...ngDevMode ? [{ debugName: "headerClasses" }] : /* istanbul ignore next */ []);
11215
+ paddingClasses = computed(() => PADDING[this.breakpoint()], ...ngDevMode ? [{ debugName: "paddingClasses" }] : /* istanbul ignore next */ []);
11216
+ widthClasses = computed(() => WIDTH[this.contentWidth()], ...ngDevMode ? [{ debugName: "widthClasses" }] : /* istanbul ignore next */ []);
11217
+ constructor() {
11218
+ afterNextRender({ read: () => this.nested.set(this.host.nativeElement.parentElement?.closest("main, [role=\"main\"]") != null) });
11219
+ }
11220
+ skip(event) {
11221
+ event.preventDefault();
11222
+ this.main().nativeElement.focus();
11223
+ }
11224
+ static ɵfac = i0.ɵɵngDeclareFactory({
11225
+ minVersion: "12.0.0",
11226
+ version: "22.1.7",
11227
+ ngImport: i0,
11228
+ type: BfAppFrameComponent,
11229
+ deps: [],
11230
+ target: i0.ɵɵFactoryTarget.Component
11231
+ });
11232
+ static ɵcmp = i0.ɵɵngDeclareComponent({
11233
+ minVersion: "17.2.0",
11234
+ version: "22.1.7",
11235
+ type: BfAppFrameComponent,
11236
+ isStandalone: true,
11237
+ selector: "bf-app-frame",
11238
+ inputs: {
11239
+ breakpoint: {
11240
+ classPropertyName: "breakpoint",
11241
+ publicName: "breakpoint",
11242
+ isSignal: true,
11243
+ isRequired: false,
11244
+ transformFunction: null
11245
+ },
11246
+ contentWidth: {
11247
+ classPropertyName: "contentWidth",
11248
+ publicName: "contentWidth",
11249
+ isSignal: true,
11250
+ isRequired: false,
11251
+ transformFunction: null
11252
+ },
11253
+ mainId: {
11254
+ classPropertyName: "mainId",
11255
+ publicName: "mainId",
11256
+ isSignal: true,
11257
+ isRequired: false,
11258
+ transformFunction: null
11259
+ }
11260
+ },
11261
+ host: { classAttribute: "bg-bg text-text relative flex" },
11262
+ viewQueries: [{
11263
+ propertyName: "main",
11264
+ first: true,
11265
+ predicate: ["main"],
11266
+ descendants: true,
11267
+ isSignal: true
11268
+ }],
11269
+ ngImport: i0,
11270
+ template: `
11271
+ <!-- The skip link focuses the content by script: under <base href="/"> a bare "#id" link
11272
+ resolves against the base, so following it would load the root URL instead of moving
11273
+ focus. The href stays for its link semantics and a copied or middle-clicked URL. -->
11274
+ <a
11275
+ data-skip-link
11276
+ [href]="'#' + mainId()"
11277
+ class="bg-surface text-text text-label-sm shadow-floating rounded-control focus-visible:ring-ring absolute start-4 top-4 z-50 px-4 py-2 font-bold not-focus:sr-only focus-visible:ring-4 focus-visible:outline-hidden"
11278
+ (click)="skip($event)"
11279
+ >{{ labels.skipToContent }}</a
11280
+ >
11281
+ <!-- From the breakpoint up the sidebar column sticks to the viewport at its full height (or
11282
+ the frame's, when a consumer gives it one); the bf-sidebar stretches to fill it and
11283
+ scrolls its own destinations. -->
11284
+ <div data-sidebar class="sticky top-0 h-dvh max-h-full shrink-0 {{ sidebarClasses() }}">
11285
+ <ng-content select="[bfSlot=sidebar]" />
11286
+ </div>
11287
+ <div data-column class="flex min-w-0 flex-1 flex-col">
11288
+ <header
11289
+ data-bar
11290
+ class="bg-surface border-border sticky top-0 z-10 min-h-14 items-center gap-3 border-b px-4 py-2 {{
11291
+ headerClasses()
11292
+ }}"
11293
+ >
11294
+ <!-- The menu at the inline start, then the brand: the top app bar convention, and the
11295
+ menu comes first in the tab order too. -->
11296
+ <div data-menu class="flex items-center empty:hidden">
11297
+ <ng-content select="[bfSlot=menu]" />
11298
+ </div>
11299
+ <div data-brand class="flex min-w-0 items-center empty:hidden">
11300
+ <ng-content select="[bfSlot=brand]" />
11301
+ </div>
11302
+ <div data-actions class="ms-auto flex items-center gap-2 empty:hidden">
11303
+ <ng-content select="[bfSlot=actions]" />
11304
+ </div>
11305
+ </header>
11306
+ <!-- A div with the main role rather than <main>: nested inside another page's main (a docs
11307
+ preview) it drops the role, so the document keeps exactly one main landmark. -->
11308
+ <div
11309
+ #main
11310
+ data-main
11311
+ [id]="mainId()"
11312
+ tabindex="-1"
11313
+ [attr.role]="nested() ? null : 'main'"
11314
+ class="min-w-0 flex-1 outline-hidden {{ paddingClasses() }}"
11315
+ >
11316
+ <div data-content class="mx-auto w-full {{ widthClasses() }}">
11317
+ <ng-content />
11318
+ </div>
11319
+ </div>
11320
+ </div>
11321
+ `,
11322
+ isInline: true
11323
+ });
11324
+ };
11325
+ i0.ɵɵngDeclareClassMetadata({
11326
+ minVersion: "12.0.0",
11327
+ version: "22.1.7",
11328
+ ngImport: i0,
11329
+ type: BfAppFrameComponent,
11330
+ decorators: [{
11331
+ type: Component,
11332
+ args: [{
11333
+ selector: "bf-app-frame",
11334
+ host: { class: "bg-bg text-text relative flex" },
11335
+ template: `
11336
+ <!-- The skip link focuses the content by script: under <base href="/"> a bare "#id" link
11337
+ resolves against the base, so following it would load the root URL instead of moving
11338
+ focus. The href stays for its link semantics and a copied or middle-clicked URL. -->
11339
+ <a
11340
+ data-skip-link
11341
+ [href]="'#' + mainId()"
11342
+ class="bg-surface text-text text-label-sm shadow-floating rounded-control focus-visible:ring-ring absolute start-4 top-4 z-50 px-4 py-2 font-bold not-focus:sr-only focus-visible:ring-4 focus-visible:outline-hidden"
11343
+ (click)="skip($event)"
11344
+ >{{ labels.skipToContent }}</a
11345
+ >
11346
+ <!-- From the breakpoint up the sidebar column sticks to the viewport at its full height (or
11347
+ the frame's, when a consumer gives it one); the bf-sidebar stretches to fill it and
11348
+ scrolls its own destinations. -->
11349
+ <div data-sidebar class="sticky top-0 h-dvh max-h-full shrink-0 {{ sidebarClasses() }}">
11350
+ <ng-content select="[bfSlot=sidebar]" />
11351
+ </div>
11352
+ <div data-column class="flex min-w-0 flex-1 flex-col">
11353
+ <header
11354
+ data-bar
11355
+ class="bg-surface border-border sticky top-0 z-10 min-h-14 items-center gap-3 border-b px-4 py-2 {{
11356
+ headerClasses()
11357
+ }}"
11358
+ >
11359
+ <!-- The menu at the inline start, then the brand: the top app bar convention, and the
11360
+ menu comes first in the tab order too. -->
11361
+ <div data-menu class="flex items-center empty:hidden">
11362
+ <ng-content select="[bfSlot=menu]" />
11363
+ </div>
11364
+ <div data-brand class="flex min-w-0 items-center empty:hidden">
11365
+ <ng-content select="[bfSlot=brand]" />
11366
+ </div>
11367
+ <div data-actions class="ms-auto flex items-center gap-2 empty:hidden">
11368
+ <ng-content select="[bfSlot=actions]" />
11369
+ </div>
11370
+ </header>
11371
+ <!-- A div with the main role rather than <main>: nested inside another page's main (a docs
11372
+ preview) it drops the role, so the document keeps exactly one main landmark. -->
11373
+ <div
11374
+ #main
11375
+ data-main
11376
+ [id]="mainId()"
11377
+ tabindex="-1"
11378
+ [attr.role]="nested() ? null : 'main'"
11379
+ class="min-w-0 flex-1 outline-hidden {{ paddingClasses() }}"
11380
+ >
11381
+ <div data-content class="mx-auto w-full {{ widthClasses() }}">
11382
+ <ng-content />
11383
+ </div>
11384
+ </div>
11385
+ </div>
11386
+ `
11387
+ }]
11388
+ }],
11389
+ ctorParameters: () => [],
11390
+ propDecorators: {
11391
+ breakpoint: [{
11392
+ type: i0.Input,
11393
+ args: [{
11394
+ isSignal: true,
11395
+ alias: "breakpoint",
11396
+ required: false
11397
+ }]
11398
+ }],
11399
+ contentWidth: [{
11400
+ type: i0.Input,
11401
+ args: [{
11402
+ isSignal: true,
11403
+ alias: "contentWidth",
11404
+ required: false
11405
+ }]
11406
+ }],
11407
+ mainId: [{
11408
+ type: i0.Input,
11409
+ args: [{
11410
+ isSignal: true,
11411
+ alias: "mainId",
11412
+ required: false
11413
+ }]
11414
+ }],
11415
+ main: [{
11416
+ type: i0.ViewChild,
11417
+ args: ["main", { isSignal: true }]
11418
+ }]
11419
+ }
11420
+ });
10771
11421
  const BAR = "relative overflow-hidden bg-surface-sunken after:absolute after:inset-0 after:bg-linear-to-r after:from-transparent after:via-surface/70 after:to-transparent after:content-[''] after:animate-skeleton-shimmer rtl:after:animate-skeleton-shimmer-rtl motion-reduce:after:hidden forced-colors:border forced-colors:border-[GrayText]";
10772
11422
  const HOST = {
10773
11423
  text: "flex flex-col gap-2",
@@ -12699,6 +13349,6 @@ function provideBfDocumentReset() {
12699
13349
  inject(DestroyRef).onDestroy(() => resetBfDocument(document));
12700
13350
  });
12701
13351
  }
12702
- export { BF_COLOR_SCHEME_STORAGE, BF_DEFAULTS, BF_DEFAULT_LABELS, BF_DEFAULT_VALUES, BF_LABELS, BF_TAB_BAR, BF_TAB_BAR_CONTROLLER, BF_TAB_LINKS, BfActionBarComponent, BfActionDirective, BfAlertComponent, BfAvatarComponent, BfBadgeComponent, BfBreadcrumbComponent, BfBreadcrumbItemComponent, BfButtonComponent, BfCalendarComponent, BfCardComponent, BfCheckboxComponent, BfChipComponent, BfChipGroupComponent, BfColorSchemeService, BfDescriptionItemComponent, BfDescriptionListComponent, BfEmptyStateComponent, BfFieldComponent, BfIconButtonComponent, BfInputComponent, BfListComponent, BfListItemComponent, BfNavGroupComponent, BfNavItemComponent, BfPageHeaderComponent, BfPaginationComponent, BfProgressComponent, BfRadioGroupComponent, BfSegmentedComponent, BfSelectComponent, BfSidebarComponent, BfSkeletonComponent, BfSpinnerComponent, BfStatComponent, BfTabBarComponent, BfTabComponent, BfTabGroupComponent, BfTabPanelComponent, BfTableCellDirective, BfTableComponent, BfTextareaComponent, BfThemeSwitchComponent, BfToggleComponent, BfToolbarComponent, BfTopNavComponent, bfFieldControlClass, bfValidationMessage, provideBfColorScheme, provideBfDefaults, provideBfLabels, BUTTON_CLASSES as ɵBF_BUTTON_CLASSES, ICON_BUTTON_CLASSES as ɵBF_ICON_BUTTON_CLASSES, FIELD_BOX as ɵFIELD_BOX, FIELD_ICON_END as ɵFIELD_ICON_END, FIELD_ICON_START as ɵFIELD_ICON_START, FIELD_PADDING_END as ɵFIELD_PADDING_END, FIELD_PADDING_START as ɵFIELD_PADDING_START, PILL_HIT as ɵPILL_HIT, compareIso as ɵcompareIso, createMemoryColorSchemeStorage as ɵcreateMemoryColorSchemeStorage, daysInMonth as ɵdaysInMonth, fieldDescribedBy as ɵfieldDescribedBy, fieldErrorMessageId as ɵfieldErrorMessageId, fieldErrorText as ɵfieldErrorText, fieldShowsError as ɵfieldShowsError, formatIsoDate as ɵformatIsoDate, localIsoDate as ɵlocalIsoDate, parseIsoDate as ɵparseIsoDate, provideBfDocumentReset as ɵprovideBfDocumentReset, uniqueId as ɵuniqueId, validIsoDate as ɵvalidIsoDate };
13352
+ export { BF_COLOR_SCHEME_STORAGE, BF_DEFAULTS, BF_DEFAULT_LABELS, BF_DEFAULT_VALUES, BF_LABELS, BF_SIDEBAR_STATE_STORAGE, BF_TAB_BAR, BF_TAB_BAR_CONTROLLER, BF_TAB_LINKS, BfActionBarComponent, BfActionDirective, BfAlertComponent, BfAppFrameComponent, BfAvatarComponent, BfBadgeComponent, BfBreadcrumbComponent, BfBreadcrumbItemComponent, BfButtonComponent, BfCalendarComponent, BfCardComponent, BfCheckboxComponent, BfChipComponent, BfChipGroupComponent, BfColorSchemeService, BfDescriptionItemComponent, BfDescriptionListComponent, BfEmptyStateComponent, BfFieldComponent, BfIconButtonComponent, BfInputComponent, BfListComponent, BfListItemComponent, BfNavGroupComponent, BfNavItemComponent, BfPageHeaderComponent, BfPaginationComponent, BfProgressComponent, BfRadioGroupComponent, BfSegmentedComponent, BfSelectComponent, BfSidebarComponent, BfSidebarStateService, BfSkeletonComponent, BfSpinnerComponent, BfStatComponent, BfTabBarComponent, BfTabComponent, BfTabGroupComponent, BfTabPanelComponent, BfTableCellDirective, BfTableComponent, BfTextareaComponent, BfThemeSwitchComponent, BfToggleComponent, BfToolbarComponent, BfTopNavComponent, bfFieldControlClass, bfValidationMessage, provideBfColorScheme, provideBfDefaults, provideBfLabels, provideBfSidebarState, BUTTON_CLASSES as ɵBF_BUTTON_CLASSES, ICON_BUTTON_CLASSES as ɵBF_ICON_BUTTON_CLASSES, BF_NAV as ɵBF_NAV, FIELD_BOX as ɵFIELD_BOX, FIELD_ICON_END as ɵFIELD_ICON_END, FIELD_ICON_START as ɵFIELD_ICON_START, FIELD_PADDING_END as ɵFIELD_PADDING_END, FIELD_PADDING_START as ɵFIELD_PADDING_START, PILL_HIT as ɵPILL_HIT, compareIso as ɵcompareIso, createMemoryColorSchemeStorage as ɵcreateMemoryColorSchemeStorage, daysInMonth as ɵdaysInMonth, fieldDescribedBy as ɵfieldDescribedBy, fieldErrorMessageId as ɵfieldErrorMessageId, fieldErrorText as ɵfieldErrorText, fieldShowsError as ɵfieldShowsError, formatIsoDate as ɵformatIsoDate, localIsoDate as ɵlocalIsoDate, parseIsoDate as ɵparseIsoDate, provideBfDocumentReset as ɵprovideBfDocumentReset, uniqueId as ɵuniqueId, validIsoDate as ɵvalidIsoDate };
12703
13353
 
12704
13354
  //# sourceMappingURL=bitforgehq-ui.mjs.map