@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
@@ -187,7 +187,7 @@ export class ToolbarStatusExampleComponent {
187
187
 
188
188
  ## Wrapping
189
189
 
190
- The row is a wrapping flex row with an 8 px gap between items and between rows. In a narrow column the filters wrap onto new rows, and the actions wrap as one group, kept together at the inline end. Give a search field a width (`class="w-full sm:w-56"`) so it fills a phone-wide row and stays compact on a wide one.
190
+ The row is a wrapping flex row with an 8 px gap between items and between rows. The status and the actions are one group that takes the rest of the last row: on a wide row the status follows the view switch and the actions sit at the inline end; when the group no longer fits beside the filters, it wraps onto a row of its own as a whole, with the status at the start and the actions at the end. So the actions never end up alone on a row, and they stay on the last filter row whenever the group fits there. Give a search field a width (`class="w-full sm:w-56"`) so it fills a phone-wide row and stays compact on a wide one.
191
191
 
192
192
  ```ts
193
193
  import { Component } from '@angular/core';
@@ -202,8 +202,8 @@ import {
202
202
  /**
203
203
  * A toolbar that wraps.
204
204
  *
205
- * In a narrow column the filters wrap onto new rows 8 px apart, and the actions move down
206
- * together, still at the inline end.
205
+ * In a narrow column the filters wrap onto new rows 8 px apart, and the status and the actions
206
+ * move down together: the count at the start of the last row, the actions at the inline end.
207
207
  */
208
208
  @Component({
209
209
  selector: 'app-example-toolbar-wrapping',
@@ -232,6 +232,63 @@ export class ToolbarWrappingExampleComponent {
232
232
  }
233
233
  ```
234
234
 
235
+ ## Phone width
236
+
237
+ At phone width (in a desktop web app's narrow window or a narrow column) the search takes a row, the filters share the next, and the status and actions share the last row. A toolbar without actions keeps the status as a plain item after the filters.
238
+
239
+ ```ts
240
+ import { Component, signal } from '@angular/core';
241
+ import {
242
+ BfButtonComponent,
243
+ BfInputComponent,
244
+ BfSelectComponent,
245
+ BfToolbarComponent,
246
+ type BfSelectOption,
247
+ } from '@bitforgehq/ui';
248
+
249
+ /**
250
+ * A toolbar at phone width.
251
+ *
252
+ * In a phone-wide column the search fills its own row, the two filters share the next one, and
253
+ * the status and the Refresh action share the last row: the count at the start, the action at the
254
+ * end, never alone on a row of its own.
255
+ */
256
+ @Component({
257
+ selector: 'app-example-toolbar-narrow',
258
+ imports: [BfButtonComponent, BfInputComponent, BfSelectComponent, BfToolbarComponent],
259
+ template: `
260
+ <div class="max-w-xs">
261
+ <bf-toolbar label="Order filters" [status]="count()">
262
+ <bf-input
263
+ type="search"
264
+ ariaLabel="Search orders"
265
+ placeholder="Search orders"
266
+ class="w-full"
267
+ />
268
+ <bf-select ariaLabel="Status" [options]="statuses" value="open" />
269
+ <bf-select ariaLabel="Period" [options]="periods" value="week" />
270
+ <bf-button bfSlot="actions" variant="outline" (clicked)="refresh()">Refresh</bf-button>
271
+ </bf-toolbar>
272
+ </div>
273
+ `,
274
+ })
275
+ export class ToolbarNarrowExampleComponent {
276
+ protected readonly count = signal('12 orders');
277
+ protected readonly statuses: BfSelectOption[] = [
278
+ { value: 'open', label: 'Open' },
279
+ { value: 'shipped', label: 'Shipped' },
280
+ ];
281
+ protected readonly periods: BfSelectOption[] = [
282
+ { value: 'week', label: 'This week' },
283
+ { value: 'month', label: 'This month' },
284
+ ];
285
+
286
+ protected refresh(): void {
287
+ this.count.set('12 orders, updated');
288
+ }
289
+ }
290
+ ```
291
+
235
292
  ## Desktop
236
293
 
237
294
  `bf-toolbar` is a desktop pattern. Every control and field projected into it resolves its unset `size` to `sm` (32 px tall), because its `providers` set `provideBfDefaults({ size: 'sm' })` for its content; a control that sets `size` itself keeps it, and nothing outside the toolbar changes ([density guide](https://bitforge-ui.web.app/density)). Hover, the pointer cursor and the `focus-visible` ring come from each control; the row adds none of its own. Under a fine pointer each control's visual box is its hit area; under a coarse pointer the `sm` touch extensions reach up to 7.5 px past the visual edge, which the 8 px gap keeps off the neighbouring row.
@@ -262,7 +319,7 @@ The `status` element is `role="status"` (an `aria-live="polite"` region), always
262
319
 
263
320
  - `default`: The search field and the filters (bf-input, bf-select, bf-chip-group), in order.
264
321
  - `view`: A view switch after the filters, such as a bf-segmented of list and grid.
265
- - `actions`: The trailing actions, kept together at the inline end of the row.
322
+ - `actions`: The trailing actions, kept together at the inline end of the row, beside the status.
266
323
 
267
324
  ## Notes
268
325
 
@@ -278,6 +335,14 @@ The `status` element is `role="status"` (an `aria-live="polite"` region), always
278
335
 
279
336
  ## Migration notes
280
337
 
338
+ ### 0.3.2
339
+
340
+ On a narrow row the actions no longer end up alone on a row of their own: the status and the
341
+ actions are now one group that takes the rest of the last row and wraps as a whole, with the
342
+ status at the start and the actions at the inline end. The wide layout is unchanged, and a
343
+ toolbar without actions keeps the status as a plain item of the row. New `toolbar/narrow`
344
+ example at phone width.
345
+
281
346
  ### 0.3.1
282
347
 
283
348
  New `bf-toolbar` in `@bitforgehq/ui`: a wrapping `role="group"` row for the search field and
@@ -0,0 +1,27 @@
1
+ # BfAppFrameBreakpoint
2
+
3
+ The breakpoint where an app frame switches from its header bar to the sidebar
4
+
5
+ Type from `@bitforgehq/ui` · since 0.3.2
6
+
7
+ The viewport width from which `bf-app-frame` shows its sidebar column instead of the narrow
8
+ header bar: Tailwind's `md` (768 px) or `lg` (1024 px).
9
+
10
+ ```ts
11
+ import { type BfAppFrameBreakpoint } from '@bitforgehq/ui';
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```ts
17
+ type BfAppFrameBreakpoint = 'md' | 'lg'
18
+ ```
19
+
20
+ ## Values
21
+
22
+ - `md`
23
+ - `lg`
24
+
25
+ ## Used by
26
+
27
+ - [bf-app-frame](../components/app-frame.md)
@@ -0,0 +1,29 @@
1
+ # BfAppFrameContentWidth
2
+
3
+ The maximum width of an app frame's content column, from medium to full
4
+
5
+ Type from `@bitforgehq/ui` · since 0.3.2
6
+
7
+ The maximum width of `bf-app-frame`'s content column: `md` 48rem, `lg` 64rem, `xl` 80rem, or
8
+ `full` for no limit.
9
+
10
+ ```ts
11
+ import { type BfAppFrameContentWidth } from '@bitforgehq/ui';
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```ts
17
+ type BfAppFrameContentWidth = 'md' | 'lg' | 'xl' | 'full'
18
+ ```
19
+
20
+ ## Values
21
+
22
+ - `md`
23
+ - `lg`
24
+ - `xl`
25
+ - `full`
26
+
27
+ ## Used by
28
+
29
+ - [bf-app-frame](../components/app-frame.md)
@@ -23,4 +23,4 @@ type BfEmptyStateHeadingLevel = 2 | 3
23
23
 
24
24
  ## Used by
25
25
 
26
- - [bf-empty-state](../components/empty-state.md)
26
+ - [BfEmptyStateHeading](bf-empty-state-heading.md)
@@ -0,0 +1,33 @@
1
+ # BfEmptyStateHeading
2
+
3
+ The heading level of an empty state title, one for a whole page
4
+
5
+ Type from `@bitforgehq/ui` · since 0.3.2
6
+
7
+ The heading level a `bf-empty-state` title takes: a `BfEmptyStateHeadingLevel`, or `1` when the
8
+ empty state is the page itself (a not-found or no-access page). A new type, so `Record`s over
9
+ the released `BfEmptyStateHeadingLevel` keep compiling.
10
+
11
+ ```ts
12
+ import { type BfEmptyStateHeading } from '@bitforgehq/ui';
13
+ ```
14
+
15
+ ## Signature
16
+
17
+ ```ts
18
+ type BfEmptyStateHeading = BfEmptyStateHeadingLevel | 1
19
+ ```
20
+
21
+ ## Values
22
+
23
+ - `2`
24
+ - `3`
25
+ - `1`
26
+
27
+ ## Uses
28
+
29
+ - [BfEmptyStateHeadingLevel](bf-empty-state-heading-level.md)
30
+
31
+ ## Used by
32
+
33
+ - [bf-empty-state](../components/empty-state.md)
@@ -32,6 +32,10 @@ import { type BfLabels } from '@bitforgehq/ui';
32
32
  | `dialog` | `string` | `'Dialog'` | A dialog's or side panel's name without an ariaLabel, a title or a heading. |
33
33
  | `notifications` | `string` | `'Notifications'` | The desktop toast stack's region name. |
34
34
  | `tableSelectAll` | `string` | `'Select all rows'` | bf-table's header checkbox, which selects or clears every row. |
35
+ | `tableSortBy` | `string` | `'Sort by'` | The label of a stacked bf-table's sort select. |
36
+ | `tableSortNone` | `string` | `'Not sorted'` | A stacked bf-table's first sort option: rows in the order given, no column sorted. |
37
+ | `tableSortAscending` | `(column: string) => string` | `` (column) => `${column}, ascending` `` | A stacked bf-table's sort option for a column in ascending order. |
38
+ | `tableSortDescending` | `(column: string) => string` | `` (column) => `${column}, descending` `` | A stacked bf-table's sort option for a column in descending order. |
35
39
  | `theme` | `string` | `'Theme'` | bf-theme-switch's and bf-theme-menu-button's name without a label. |
36
40
  | `themeSystem` | `string` | `'System'` | The theme choice that follows the system's colour scheme. |
37
41
  | `themeLight` | `string` | `'Light'` | The theme choice that forces the light colour scheme. |
@@ -40,6 +44,9 @@ import { type BfLabels } from '@bitforgehq/ui';
40
44
  | `breadcrumbExpand` | `(count: number) => string` | ``(count) => (count === 1 ? 'Show 1 more level' : `Show ${count} more levels`)`` | bf-breadcrumb's ellipsis button, which shows the levels a `maxItems` trail hides. |
41
45
  | `navigation` | `string` | `'Main'` | bf-sidebar's and bf-top-nav's navigation name. |
42
46
  | `navBadge` | `(count: number) => string` | `` (count) => `${count} new` `` | a[bfNavItem]'s announcement of its count badge. |
47
+ | `sidebarCollapse` | `string` | `'Collapse sidebar'` | bf-sidebar-toggle's name and tooltip while the sidebar is expanded. |
48
+ | `sidebarExpand` | `string` | `'Expand sidebar'` | bf-sidebar-toggle's name and tooltip while the sidebar is an icon rail. |
49
+ | `skipToContent` | `string` | `'Skip to main content'` | bf-app-frame's skip link, the first stop of the tab order, which moves focus to the content. |
43
50
  | `pagination` | `string` | `'Pagination'` | bf-pagination's navigation name. |
44
51
  | `previousPage` | `string` | `'Previous page'` | bf-pagination's button to the previous page. |
45
52
  | `nextPage` | `string` | `'Next page'` | bf-pagination's button to the next page. |
@@ -68,3 +68,7 @@ Focuses the native select.
68
68
  ### `blur(): Promise<void>`
69
69
 
70
70
  Blurs the native select, which marks a bound form field touched.
71
+
72
+ ## Used by
73
+
74
+ - [BfTableHarness](bf-table-harness.md)
@@ -0,0 +1,21 @@
1
+ # BfSidebarStateService
2
+
3
+ The sidebar's collapsed state, kept in storage between visits of the app
4
+
5
+ Service from `@bitforgehq/ui` · since 0.3.2
6
+
7
+ Whether the app's `bf-sidebar` is collapsed to an icon rail, remembered between visits: the app
8
+ binds the sidebar's `[(collapsed)]` to `sidebarState.collapsed`. With `provideBfSidebarState()`
9
+ every change is stored in `BF_SIDEBAR_STATE_STORAGE` under `bf-sidebar-collapsed`; without it
10
+ the signal still holds the state but nothing is written. Storage is read in the browser only, so a
11
+ server render starts expanded and writes nothing. The widgets never inject it.
12
+
13
+ ```ts
14
+ import { BfSidebarStateService } from '@bitforgehq/ui';
15
+ ```
16
+
17
+ ## Properties
18
+
19
+ | Name | Type | Default | Description |
20
+ | ----------- | ------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------- |
21
+ | `collapsed` | `WritableSignal<boolean>` | | Whether the sidebar is collapsed: the stored state in the browser, else false. Bind it two-way to `bf-sidebar`'s `collapsed`. |
@@ -0,0 +1,32 @@
1
+ # BfSidebarToggleHarness
2
+
3
+ Test harness for a sidebar toggle: reads and flips the collapsed sidebar
4
+
5
+ Class from `@bitforgehq/ui/testing` · since 0.3.2
6
+
7
+ Harness for `bf-sidebar-toggle`, the button that collapses a `bf-sidebar` to an icon rail. Its
8
+ `label` filter matches the button's name ("Collapse sidebar" or "Expand sidebar").
9
+
10
+ ```ts
11
+ import { BfSidebarToggleHarness } from '@bitforgehq/ui/testing';
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```ts
17
+ class BfSidebarToggleHarness extends ComponentHarness
18
+ ```
19
+
20
+ ## Methods
21
+
22
+ ### `getLabel(): Promise<string>`
23
+
24
+ The button's name, which says what the next press does.
25
+
26
+ ### `isExpanded(): Promise<boolean>`
27
+
28
+ Whether the sidebar is at full width (`aria-expanded`).
29
+
30
+ ### `toggle(): Promise<void>`
31
+
32
+ Flips the sidebar with a click.
@@ -48,6 +48,7 @@ type BfSize = 'sm' | 'md' | 'lg'
48
48
  - [bf-segmented](../components/segmented.md)
49
49
  - [BfSegmentedSize](bf-segmented-size.md)
50
50
  - [bf-select](../components/select.md)
51
+ - [bf-sidebar-toggle](../components/sidebar-toggle.md)
51
52
  - [bf-tab-group](../components/tab-group.md)
52
53
  - [bf-table](../components/table.md)
53
54
  - [bf-textarea](../components/textarea.md)
@@ -0,0 +1,33 @@
1
+ # BfStatAppearance
2
+
3
+ The three stat surfaces, plain, an outlined card or a sunken tile
4
+
5
+ Type from `@bitforgehq/ui` · since 0.3.2
6
+
7
+ The surface of a `bf-stat`, as its `variant` input takes it: a `BfStatVariant` or tile (a
8
+ sunken, borderless tile for a stats row inside a raised card). A new type, so `Record`s over
9
+ the released `BfStatVariant` keep compiling.
10
+
11
+ ```ts
12
+ import { type BfStatAppearance } from '@bitforgehq/ui';
13
+ ```
14
+
15
+ ## Signature
16
+
17
+ ```ts
18
+ type BfStatAppearance = BfStatVariant | 'tile'
19
+ ```
20
+
21
+ ## Values
22
+
23
+ - `plain`
24
+ - `card`
25
+ - `tile`
26
+
27
+ ## Uses
28
+
29
+ - [BfStatVariant](bf-stat-variant.md)
30
+
31
+ ## Used by
32
+
33
+ - [bf-stat](../components/stat.md)
@@ -23,4 +23,4 @@ type BfStatVariant = 'plain' | 'card'
23
23
 
24
24
  ## Used by
25
25
 
26
- - [bf-stat](../components/stat.md)
26
+ - [BfStatAppearance](bf-stat-appearance.md)
@@ -6,7 +6,7 @@ Class from `@bitforgehq/ui/testing` · since 0.3.1
6
6
 
7
7
  Harness for `bf-table`. It works by column header text and row position, so a test never needs
8
8
  the column keys or the row keys (except `getSort()`, which returns the column's `key`, as the
9
- `sort` model holds it).
9
+ `sort` model holds it). It reads and drives a stacked table (`stack`) the same way.
10
10
 
11
11
  ```ts
12
12
  import { BfTableHarness } from '@bitforgehq/ui/testing';
@@ -54,6 +54,11 @@ Throws for an unknown or unsortable column.
54
54
 
55
55
  The sorted column (its `key`) and direction, from `aria-sort`.
56
56
 
57
+ ### `getSortSelect(): Promise<BfSelectHarness | null>`
58
+
59
+ The Sort by select in a stacked table's bar: its first option, Not sorted (`tableSortNone`),
60
+ sets `sort` to null and shows while it is; then each sortable column ascending and descending.
61
+
57
62
  ### `selectRow(index: number): Promise<void>`
58
63
 
59
64
  Checks one row's checkbox, as a user would; a selected row stays selected. Throws when the
@@ -74,4 +79,5 @@ The number of selected rows (checked row checkboxes).
74
79
 
75
80
  ## Uses
76
81
 
82
+ - [BfSelectHarness](bf-select-harness.md)
77
83
  - [BfTableSort](bf-table-sort.md)
@@ -0,0 +1,29 @@
1
+ # BfTableStack
2
+
3
+ When a table stacks its rows into cards: never, when narrow, or under touch
4
+
5
+ Type from `@bitforgehq/ui` · since 0.3.2
6
+
7
+ When a `bf-table` renders each row as a card of label/value pairs: `never` (the default),
8
+ `narrow` while the table is narrower than 36rem (a container query), or `coarse` under a coarse
9
+ pointer at any width.
10
+
11
+ ```ts
12
+ import { type BfTableStack } from '@bitforgehq/ui';
13
+ ```
14
+
15
+ ## Signature
16
+
17
+ ```ts
18
+ type BfTableStack = 'never' | 'narrow' | 'coarse'
19
+ ```
20
+
21
+ ## Values
22
+
23
+ - `never`
24
+ - `narrow`
25
+ - `coarse`
26
+
27
+ ## Used by
28
+
29
+ - [bf-table](../components/table.md)
@@ -0,0 +1,20 @@
1
+ # BF_SIDEBAR_STATE_STORAGE
2
+
3
+ Injection token for the store that keeps the collapsed sidebar between visits
4
+
5
+ Injection token from `@bitforgehq/ui` · since 0.3.2
6
+
7
+ Where `BfSidebarStateService` keeps whether the sidebar is collapsed (the key
8
+ `bf-sidebar-collapsed`, `'true'` or `'false'`): `localStorage` when it is available, otherwise
9
+ an in-memory map. Provide another store (`sessionStorage`, or an in-memory one in tests) to keep
10
+ it elsewhere.
11
+
12
+ ```ts
13
+ import { BF_SIDEBAR_STATE_STORAGE } from '@bitforgehq/ui';
14
+ ```
15
+
16
+ ## Signature
17
+
18
+ ```ts
19
+ const BF_SIDEBAR_STATE_STORAGE: InjectionToken<Pick<Storage, "getItem" | "setItem">>
20
+ ```
@@ -7,9 +7,10 @@ Function from `@bitforgehq/ui` · since 0.3.0
7
7
  Replaces built-in strings, merged over the parent's (validation merged key by key); a key left
8
8
  out or set to `undefined` keeps the parent's string. In `ApplicationConfig.providers` it covers
9
9
  every string. In a component's `providers` it covers that sub-tree's widgets and form controls
10
- (`loading`, `dismiss`, `tabBar`, `tabBadge`, `back`, `refreshing`, `tableSelectAll`, `theme`,
11
- `themeSystem`, `themeLight`, `themeDark`, `breadcrumb`, `breadcrumbExpand`, `navigation`,
12
- `navBadge`, `pagination`, `previousPage`, `nextPage`, `pageOf`, `goToPage`, `tabGroup`,
10
+ (`loading`, `dismiss`, `tabBar`, `tabBadge`, `back`, `refreshing`, `tableSelectAll`, `tableSortBy`,
11
+ `tableSortNone`, `tableSortAscending`, `tableSortDescending`, `theme`, `themeSystem`, `themeLight`, `themeDark`,
12
+ `breadcrumb`, `breadcrumbExpand`, `navigation`, `navBadge`, `sidebarCollapse`, `sidebarExpand`,
13
+ `skipToContent`, `pagination`, `previousPage`, `nextPage`, `pageOf`, `goToPage`, `tabGroup`,
13
14
  `calendarPreviousMonth`, `calendarNextMonth`, `calendarChooseMonth`, `calendarChooseYear`,
14
15
  `statTrendUp`, `statTrendDown`, `statTrendFlat`, `comboboxEmpty`, `comboboxRemove`,
15
16
  `dateInputDay`, `dateInputMonth`, `dateInputYear`, `dateInputOpenCalendar`, `dateInputInvalid`,
@@ -0,0 +1,20 @@
1
+ # provideBfSidebarState
2
+
3
+ Remembers the collapsed sidebar between visits, for desktop web apps
4
+
5
+ Function from `@bitforgehq/ui` · since 0.3.2
6
+
7
+ Lets `BfSidebarStateService` remember the collapsed sidebar: it stores every change of its
8
+ `collapsed` signal (key `bf-sidebar-collapsed`, `localStorage` in the browser), so the app opens
9
+ with the sidebar as the user left it. Add it to `ApplicationConfig.providers` and bind the
10
+ sidebar's `[(collapsed)]` to `sidebarState.collapsed`.
11
+
12
+ ```ts
13
+ import { provideBfSidebarState } from '@bitforgehq/ui';
14
+ ```
15
+
16
+ ## Signature
17
+
18
+ ```ts
19
+ function provideBfSidebarState(): EnvironmentProviders
20
+ ```