@bitforgehq/ui 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +482 -0
- package/README.md +17 -11
- package/ai/MANIFEST.index.json +288 -0
- package/ai/MANIFEST.json +8716 -3926
- package/ai/REFERENCE.index.json +413 -0
- package/ai/REFERENCE.json +4710 -2047
- package/ai/UI_GUIDE.md +185 -57
- package/ai/components/back-button.md +42 -2
- package/ai/components/badge.md +17 -7
- package/ai/components/bar-chart.md +188 -0
- package/ai/components/breadcrumb-item.md +121 -0
- package/ai/components/breadcrumb.md +277 -0
- package/ai/components/button.md +82 -15
- package/ai/components/calendar.md +300 -0
- package/ai/components/card.md +63 -2
- package/ai/components/chart-card.md +283 -0
- package/ai/components/combobox.md +411 -0
- package/ai/components/date-input.md +396 -0
- package/ai/components/datetime-input.md +215 -0
- package/ai/components/description-item.md +111 -0
- package/ai/components/description-list.md +160 -0
- package/ai/components/donut-chart.md +169 -0
- package/ai/components/header.md +67 -2
- package/ai/components/icon-button.md +74 -16
- package/ai/components/icon.md +63 -7
- package/ai/components/line-chart.md +234 -0
- package/ai/components/list.md +70 -6
- package/ai/components/menu.md +5 -0
- package/ai/components/multi-combobox.md +257 -0
- package/ai/components/nav-group.md +178 -0
- package/ai/components/nav-item.md +210 -0
- package/ai/components/page-header.md +237 -0
- package/ai/components/pagination.md +173 -0
- package/ai/components/popover.md +250 -0
- package/ai/components/side-panel.md +391 -0
- package/ai/components/sidebar.md +363 -0
- package/ai/components/skeleton.md +215 -0
- package/ai/components/sparkline.md +188 -0
- package/ai/components/stat.md +233 -0
- package/ai/components/tab-group.md +226 -0
- package/ai/components/tab-panel.md +163 -0
- package/ai/components/table.md +568 -0
- package/ai/components/tabs.md +42 -2
- package/ai/components/theme-menu-button.md +182 -0
- package/ai/components/theme-switch.md +170 -0
- package/ai/components/time-input.md +240 -0
- package/ai/components/toolbar.md +289 -0
- package/ai/components/tooltip.md +230 -0
- package/ai/components/top-nav.md +159 -0
- package/ai/reference/bf-badge-appearance.md +36 -0
- package/ai/reference/bf-badge-variant.md +1 -1
- package/ai/reference/bf-bar-chart-orientation.md +27 -0
- package/ai/reference/bf-button-appearance.md +36 -0
- package/ai/reference/bf-button-variant.md +1 -1
- package/ai/reference/bf-calendar-disabled-date.md +23 -0
- package/ai/reference/bf-calendar-harness.md +51 -0
- package/ai/reference/bf-calendar-weekday.md +31 -0
- package/ai/reference/bf-chart-card-heading-level.md +26 -0
- package/ai/reference/bf-chart-curve.md +28 -0
- package/ai/reference/bf-chart-harness.md +51 -0
- package/ai/reference/bf-chart-legend-position.md +30 -0
- package/ai/reference/bf-chart-series.md +23 -0
- package/ai/reference/bf-chart-value-format.md +23 -0
- package/ai/reference/bf-color-scheme-service.md +30 -0
- package/ai/reference/bf-color-scheme.md +31 -0
- package/ai/reference/bf-combobox-filter.md +27 -0
- package/ai/reference/bf-combobox-harness.md +89 -0
- package/ai/reference/bf-combobox-option.md +33 -0
- package/ai/reference/bf-compare-with.md +2 -0
- package/ai/reference/bf-date-input-harness.md +67 -0
- package/ai/reference/bf-date-input-picker.md +27 -0
- package/ai/reference/bf-date-time-input-harness.md +76 -0
- package/ai/reference/bf-date-time-input-picker.md +27 -0
- package/ai/reference/bf-description-list-layout.md +26 -0
- package/ai/reference/bf-donut-slice.md +22 -0
- package/ai/reference/bf-labels.md +67 -20
- package/ai/reference/bf-menu-button-variant.md +1 -0
- package/ai/reference/bf-menu-placement.md +1 -0
- package/ai/reference/bf-overlay-options.md +28 -27
- package/ai/reference/bf-overlay-placement.md +34 -0
- package/ai/reference/bf-overlay-position.md +1 -1
- package/ai/reference/bf-overlay-service.md +5 -3
- package/ai/reference/bf-page-header-heading-level.md +26 -0
- package/ai/reference/bf-pagination-harness.md +61 -0
- package/ai/reference/bf-platform-service.md +17 -15
- package/ai/reference/bf-popover-harness.md +42 -0
- package/ai/reference/bf-popover-placement.md +28 -0
- package/ai/reference/bf-popover-trigger-directive.md +56 -0
- package/ai/reference/bf-side-panel-config.md +35 -0
- package/ai/reference/bf-side-panel-harness.md +34 -0
- package/ai/reference/bf-side-panel-ref.md +44 -0
- package/ai/reference/bf-side-panel-service.md +43 -0
- package/ai/reference/bf-side-panel-template-context.md +32 -0
- package/ai/reference/bf-side-panel-width.md +28 -0
- package/ai/reference/bf-size.md +12 -0
- package/ai/reference/bf-skeleton-shape.md +28 -0
- package/ai/reference/bf-stat-trend-intent.md +27 -0
- package/ai/reference/bf-stat-trend.md +27 -0
- package/ai/reference/bf-stat-variant.md +26 -0
- package/ai/reference/bf-tab-group-harness.md +44 -0
- package/ai/reference/bf-table-align.md +26 -0
- package/ai/reference/bf-table-cell-context.md +24 -0
- package/ai/reference/bf-table-cell-directive.md +22 -0
- package/ai/reference/bf-table-column.md +28 -0
- package/ai/reference/bf-table-harness.md +77 -0
- package/ai/reference/bf-table-row-key.md +21 -0
- package/ai/reference/bf-table-sort-direction.md +26 -0
- package/ai/reference/bf-table-sort.md +27 -0
- package/ai/reference/bf-theme.md +5 -4
- package/ai/reference/bf-time-input-harness.md +67 -0
- package/ai/reference/bf-time-input-hour-cycle.md +27 -0
- package/ai/reference/bf-time-input-picker.md +27 -0
- package/ai/reference/bf-tooltip-directive.md +43 -0
- package/ai/reference/bf-tooltip-harness.md +43 -0
- package/ai/reference/bf-tooltip-placement.md +28 -0
- package/ai/reference/bf_color_scheme_storage.md +20 -0
- package/ai/reference/bf_side_panel_data.md +17 -0
- package/ai/reference/bf_theme_storage.md +3 -1
- package/ai/reference/provide-bf-color-scheme.md +20 -0
- package/ai/reference/provide-bf-labels.md +12 -4
- package/ai/reference/slide-in-from-end.md +24 -0
- package/ai/reference/slide-out-to-end.md +24 -0
- package/fesm2022/bitforgehq-ui-charts.mjs +3045 -0
- package/fesm2022/bitforgehq-ui-charts.mjs.map +1 -0
- package/fesm2022/bitforgehq-ui-icons.mjs +107 -3
- package/fesm2022/bitforgehq-ui-icons.mjs.map +1 -1
- package/fesm2022/bitforgehq-ui-mobile.mjs +14 -59
- package/fesm2022/bitforgehq-ui-mobile.mjs.map +1 -1
- package/fesm2022/bitforgehq-ui-overlay.mjs +6436 -33
- package/fesm2022/bitforgehq-ui-overlay.mjs.map +1 -1
- package/fesm2022/bitforgehq-ui-testing.mjs +618 -1
- package/fesm2022/bitforgehq-ui-testing.mjs.map +1 -1
- package/fesm2022/bitforgehq-ui.mjs +5092 -153
- package/fesm2022/bitforgehq-ui.mjs.map +1 -1
- package/llms-full.txt +25177 -14398
- package/llms.txt +95 -1
- package/package.json +7 -3
- package/theme.css +101 -0
- package/types/bitforgehq-ui-charts.d.ts +967 -0
- package/types/bitforgehq-ui-icons.d.ts +13 -1
- package/types/bitforgehq-ui-mobile.d.ts +25 -18
- package/types/bitforgehq-ui-overlay.d.ts +1844 -7
- package/types/bitforgehq-ui-testing.d.ts +748 -1
- package/types/bitforgehq-ui.d.ts +2136 -44
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# div[bfDescriptionItem]
|
|
2
|
+
|
|
3
|
+
One label and value pair of a description list, label as term, content as value
|
|
4
|
+
|
|
5
|
+
`BfDescriptionItemComponent` from `@bitforgehq/ui` · Data display · since 0.3.1
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Component } from '@angular/core';
|
|
11
|
+
import { BfDescriptionItemComponent, BfDescriptionListComponent } from '@bitforgehq/ui';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The bf-description-item overview.
|
|
15
|
+
*
|
|
16
|
+
* Live demo of `div[bfDescriptionItem]`: three pairs of a recipe, each a label and its value, in a
|
|
17
|
+
* `bf-description-list`.
|
|
18
|
+
*/
|
|
19
|
+
@Component({
|
|
20
|
+
selector: 'app-example-description-item-overview',
|
|
21
|
+
imports: [BfDescriptionItemComponent, BfDescriptionListComponent],
|
|
22
|
+
template: `
|
|
23
|
+
<bf-description-list>
|
|
24
|
+
<div bfDescriptionItem label="Oven">200 °C, fan 180 °C</div>
|
|
25
|
+
<div bfDescriptionItem label="Keeps">2 days in the fridge</div>
|
|
26
|
+
<div bfDescriptionItem label="Freezes">Yes, up to 3 months</div>
|
|
27
|
+
</bf-description-list>
|
|
28
|
+
`,
|
|
29
|
+
})
|
|
30
|
+
export class DescriptionItemOverviewExampleComponent {}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Overview
|
|
34
|
+
|
|
35
|
+
One label-value pair of a `bf-description-list`: the `label` becomes the `dt`, the content the
|
|
36
|
+
`dd`. Put it on a `div` inside the list.
|
|
37
|
+
|
|
38
|
+
One label-value pair of a [`bf-description-list`](https://bitforge-ui.web.app/components/description-list): put `bfDescriptionItem` on a `div` inside the list, set its `label`, and put the value in its content. The `label` becomes the pair's `dt` and the content its `dd`; the item takes its look (a divided row or a tile) from the list's `layout`. It works the same in both shells.
|
|
39
|
+
|
|
40
|
+
## When to use
|
|
41
|
+
|
|
42
|
+
Use `div[bfDescriptionItem]` for each fact inside a `bf-description-list`. Use [bf-list-item](https://bitforge-ui.web.app/components/list-item) instead for a row the user can open or act on, and [bf-stat](https://bitforge-ui.web.app/components/stat) instead for a single headline figure.
|
|
43
|
+
|
|
44
|
+
## Basic usage
|
|
45
|
+
|
|
46
|
+
`label` is required; the value is the content, so it can be text, a badge or a link. A class on the item (such as `col-span-full` in the grid layout) is kept alongside the item's own classes.
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { Component } from '@angular/core';
|
|
50
|
+
import { BfDescriptionItemComponent, BfDescriptionListComponent } from '@bitforgehq/ui';
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The bf-description-item overview.
|
|
54
|
+
*
|
|
55
|
+
* Live demo of `div[bfDescriptionItem]`: three pairs of a recipe, each a label and its value, in a
|
|
56
|
+
* `bf-description-list`.
|
|
57
|
+
*/
|
|
58
|
+
@Component({
|
|
59
|
+
selector: 'app-example-description-item-overview',
|
|
60
|
+
imports: [BfDescriptionItemComponent, BfDescriptionListComponent],
|
|
61
|
+
template: `
|
|
62
|
+
<bf-description-list>
|
|
63
|
+
<div bfDescriptionItem label="Oven">200 °C, fan 180 °C</div>
|
|
64
|
+
<div bfDescriptionItem label="Keeps">2 days in the fridge</div>
|
|
65
|
+
<div bfDescriptionItem label="Freezes">Yes, up to 3 months</div>
|
|
66
|
+
</bf-description-list>
|
|
67
|
+
`,
|
|
68
|
+
})
|
|
69
|
+
export class DescriptionItemOverviewExampleComponent {}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Desktop
|
|
73
|
+
|
|
74
|
+
The item is not interactive: no hover, no pointer cursor, no focus stop; only a link or button in its value takes focus. It renders the same inside `provideBfShell()`.
|
|
75
|
+
|
|
76
|
+
## Theming
|
|
77
|
+
|
|
78
|
+
- Label (`dt`): `text-caption` in `text-muted`. Value (`dd`): `text-body` in `text`; a long value wraps anywhere rather than overflow.
|
|
79
|
+
- In the `rows` layout the item has `py-3` and, from a 28rem wide list, a one-third label column; in the `grid` layout it is a tile with the label over the value.
|
|
80
|
+
|
|
81
|
+
## Accessibility
|
|
82
|
+
|
|
83
|
+
The item is the `div` that groups one `dt` with its `dd` inside the list's `dl`, which HTML allows, so the pair is announced as a term and its description. It adds no ARIA.
|
|
84
|
+
|
|
85
|
+
## Inputs
|
|
86
|
+
|
|
87
|
+
| Name | Type | Default | Description |
|
|
88
|
+
| ------- | -------- | -------- | ------------------------------------ |
|
|
89
|
+
| `label` | `string` | required | The term, shown as the pair's label. |
|
|
90
|
+
|
|
91
|
+
## Slots
|
|
92
|
+
|
|
93
|
+
- `default`: The value: text or rich content such as a badge or a link.
|
|
94
|
+
|
|
95
|
+
## Notes
|
|
96
|
+
|
|
97
|
+
### Do
|
|
98
|
+
|
|
99
|
+
- Use one item per fact, with a short noun as the `label`.
|
|
100
|
+
|
|
101
|
+
### Don't
|
|
102
|
+
|
|
103
|
+
- Don't use `bfDescriptionItem` outside a `bf-description-list`: without the `dl` around it, its `dt` and `dd` are invalid HTML.
|
|
104
|
+
- Don't put a second term in one item; give each its own.
|
|
105
|
+
|
|
106
|
+
## Migration notes
|
|
107
|
+
|
|
108
|
+
### 0.3.1
|
|
109
|
+
|
|
110
|
+
New: `div[bfDescriptionItem]`, one pair of a `bf-description-list`: its required `label` is the
|
|
111
|
+
`dt`, its content (text, a badge, a link) the `dd`.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# bf-description-list
|
|
2
|
+
|
|
3
|
+
Native description list of label-value pairs, as divided rows or a tile grid
|
|
4
|
+
|
|
5
|
+
`BfDescriptionListComponent` from `@bitforgehq/ui` · Data display · since 0.3.1
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Component } from '@angular/core';
|
|
11
|
+
import {
|
|
12
|
+
BfBadgeComponent,
|
|
13
|
+
BfDescriptionItemComponent,
|
|
14
|
+
BfDescriptionListComponent,
|
|
15
|
+
} from '@bitforgehq/ui';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The bf-description-list overview.
|
|
19
|
+
*
|
|
20
|
+
* Live demo of `bf-description-list`: a recipe's details as divided rows, with a badge and a link
|
|
21
|
+
* as values; the labels move beside the values once the list is wide enough.
|
|
22
|
+
*/
|
|
23
|
+
@Component({
|
|
24
|
+
selector: 'app-example-description-list-overview',
|
|
25
|
+
imports: [BfBadgeComponent, BfDescriptionItemComponent, BfDescriptionListComponent],
|
|
26
|
+
template: `
|
|
27
|
+
<bf-description-list>
|
|
28
|
+
<div bfDescriptionItem label="Recipe">Lemon risotto with peas</div>
|
|
29
|
+
<div bfDescriptionItem label="Cuisine">Italian</div>
|
|
30
|
+
<div bfDescriptionItem label="Difficulty"><bf-badge variant="success">Easy</bf-badge></div>
|
|
31
|
+
<div bfDescriptionItem label="Diet">Vegetarian, gluten-free</div>
|
|
32
|
+
<div bfDescriptionItem label="Source">
|
|
33
|
+
<a href="#source" class="text-primary underline">Nonna's notebook, page 42</a>
|
|
34
|
+
</div>
|
|
35
|
+
<div bfDescriptionItem label="Added">12 October 2026</div>
|
|
36
|
+
</bf-description-list>
|
|
37
|
+
`,
|
|
38
|
+
})
|
|
39
|
+
export class DescriptionListOverviewExampleComponent {}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Overview
|
|
43
|
+
|
|
44
|
+
A list of label-value pairs, such as a record's details: a native `dl` around
|
|
45
|
+
`div[bfDescriptionItem]`s, as divided rows (label beside value) or a grid of tiles.
|
|
46
|
+
|
|
47
|
+
A description list shows the details of one record as label-value pairs: a recipe's cuisine and difficulty, an order's status and date, a person's role and email. `bf-description-list` renders the native `dl`; each pair is a [`div[bfDescriptionItem]`](https://bitforge-ui.web.app/components/description-item) whose `label` becomes the `dt` and whose content becomes the `dd`. It works the same in both shells: in the Capacitor shell and in a desktop web app.
|
|
48
|
+
|
|
49
|
+
## When to use
|
|
50
|
+
|
|
51
|
+
Use `bf-description-list` for read-only facts about one thing, where the reader looks up a value by its label. Use [bf-list](https://bitforge-ui.web.app/components/list) instead when the rows are actions or links, and [bf-stat](https://bitforge-ui.web.app/components/stat) instead for a few headline figures (a duration, a count, a total) that should read at a glance. A table compares many records across columns; a description list describes one.
|
|
52
|
+
|
|
53
|
+
## Rows
|
|
54
|
+
|
|
55
|
+
`layout="rows"` (the default) separates the pairs with a `border` line, as a divided `bf-list`. Once the list is 28rem wide or more, the label sits beside its value in a one-third column; in a narrower list (a phone, a side pane) the label stacks over the value. The width that counts is the list's own (the host is an inline-size container), not the viewport's, so the same list stacks in a narrow pane and sits side by side on a wide page. The value can be rich content: a badge, a link, a short sentence.
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { Component } from '@angular/core';
|
|
59
|
+
import {
|
|
60
|
+
BfBadgeComponent,
|
|
61
|
+
BfDescriptionItemComponent,
|
|
62
|
+
BfDescriptionListComponent,
|
|
63
|
+
} from '@bitforgehq/ui';
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The bf-description-list overview.
|
|
67
|
+
*
|
|
68
|
+
* Live demo of `bf-description-list`: a recipe's details as divided rows, with a badge and a link
|
|
69
|
+
* as values; the labels move beside the values once the list is wide enough.
|
|
70
|
+
*/
|
|
71
|
+
@Component({
|
|
72
|
+
selector: 'app-example-description-list-overview',
|
|
73
|
+
imports: [BfBadgeComponent, BfDescriptionItemComponent, BfDescriptionListComponent],
|
|
74
|
+
template: `
|
|
75
|
+
<bf-description-list>
|
|
76
|
+
<div bfDescriptionItem label="Recipe">Lemon risotto with peas</div>
|
|
77
|
+
<div bfDescriptionItem label="Cuisine">Italian</div>
|
|
78
|
+
<div bfDescriptionItem label="Difficulty"><bf-badge variant="success">Easy</bf-badge></div>
|
|
79
|
+
<div bfDescriptionItem label="Diet">Vegetarian, gluten-free</div>
|
|
80
|
+
<div bfDescriptionItem label="Source">
|
|
81
|
+
<a href="#source" class="text-primary underline">Nonna's notebook, page 42</a>
|
|
82
|
+
</div>
|
|
83
|
+
<div bfDescriptionItem label="Added">12 October 2026</div>
|
|
84
|
+
</bf-description-list>
|
|
85
|
+
`,
|
|
86
|
+
})
|
|
87
|
+
export class DescriptionListOverviewExampleComponent {}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Grid
|
|
91
|
+
|
|
92
|
+
`layout="grid"` lays the pairs out as tiles with the label over the value, in as many columns of at least 10rem as fit, so the tiles wrap on their own without a breakpoint. Use it for short values that read well side by side; a long value belongs in the rows layout.
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { Component } from '@angular/core';
|
|
96
|
+
import { BfDescriptionItemComponent, BfDescriptionListComponent } from '@bitforgehq/ui';
|
|
97
|
+
|
|
98
|
+
/** A recipe's nutrition per serving as a grid of tiles that wraps by itself. */
|
|
99
|
+
@Component({
|
|
100
|
+
selector: 'app-example-description-list-grid',
|
|
101
|
+
imports: [BfDescriptionItemComponent, BfDescriptionListComponent],
|
|
102
|
+
template: `
|
|
103
|
+
<bf-description-list layout="grid">
|
|
104
|
+
<div bfDescriptionItem label="Energy">520 kcal</div>
|
|
105
|
+
<div bfDescriptionItem label="Protein">16 g</div>
|
|
106
|
+
<div bfDescriptionItem label="Carbohydrates">78 g</div>
|
|
107
|
+
<div bfDescriptionItem label="Fat">14 g</div>
|
|
108
|
+
<div bfDescriptionItem label="Note" class="col-span-full">
|
|
109
|
+
Values per serving, with parmesan.
|
|
110
|
+
</div>
|
|
111
|
+
</bf-description-list>
|
|
112
|
+
`,
|
|
113
|
+
})
|
|
114
|
+
export class DescriptionListGridExampleComponent {}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Desktop
|
|
118
|
+
|
|
119
|
+
The list is not interactive: it has no hover, no pointer cursor and no focus stop of its own, and only the links or buttons you put in a value take focus. Its spacing does not follow `provideBfDefaults()`; the rows keep one rhythm on every density. Inside `provideBfShell()` (the Capacitor shell) it renders and behaves exactly the same. Because the host is an inline-size container, give it a width when you place it in a flex row (`flex-1` or a `basis-*`), or it shrinks to nothing.
|
|
120
|
+
|
|
121
|
+
## Theming
|
|
122
|
+
|
|
123
|
+
- Label (`dt`): `text-caption` in `text-muted`. Value (`dd`): `text-body` in `text`.
|
|
124
|
+
- `rows`: the lines between the pairs are `border`; each pair has `py-3` (12 px) of block padding.
|
|
125
|
+
- `grid`: `gap-x-6` / `gap-y-4` between the tiles, columns of at least 10rem.
|
|
126
|
+
|
|
127
|
+
## Accessibility
|
|
128
|
+
|
|
129
|
+
`bf-description-list` renders a native `dl`, and each `div[bfDescriptionItem]` is a `div` holding one `dt` and one `dd`, which is valid HTML, so screen readers announce a list of terms with their descriptions. The list adds no ARIA. Content in a value carries its own semantics: a badge's text is read with the value, a link stays a link.
|
|
130
|
+
|
|
131
|
+
## Inputs
|
|
132
|
+
|
|
133
|
+
| Name | Type | Default | Description |
|
|
134
|
+
| -------- | ---------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
135
|
+
| `layout` | `BfDescriptionListLayout` (`'rows' \| 'grid'`) | `'rows'` | `rows` (default): label beside value, divided, stacked in a narrow list; `grid`: tiles with the label over the value. |
|
|
136
|
+
|
|
137
|
+
## Slots
|
|
138
|
+
|
|
139
|
+
- `default`: The pairs, each a `div[bfDescriptionItem]`.
|
|
140
|
+
|
|
141
|
+
## Notes
|
|
142
|
+
|
|
143
|
+
### Do
|
|
144
|
+
|
|
145
|
+
- Keep labels short nouns ("Cuisine", "Servings") and put the unit in the value ("45 min").
|
|
146
|
+
- Put a badge or a link in a value when the value is a status or points elsewhere.
|
|
147
|
+
|
|
148
|
+
### Don't
|
|
149
|
+
|
|
150
|
+
- Don't put anything but `div[bfDescriptionItem]` pairs in a `bf-description-list`; a `dl` expects term and description groups.
|
|
151
|
+
- Don't use it for rows the user acts on; that is a `bf-list` of `bf-list-item` rows.
|
|
152
|
+
|
|
153
|
+
## Migration notes
|
|
154
|
+
|
|
155
|
+
### 0.3.1
|
|
156
|
+
|
|
157
|
+
New: `bf-description-list`, a native `dl` of label-value pairs for the details of one record, in
|
|
158
|
+
both shells. `layout="rows"` (default) divides the pairs with a `border` line and puts the label
|
|
159
|
+
beside the value once the list is 28rem wide (a container query, so a narrow pane stacks them);
|
|
160
|
+
`layout="grid"` lays them out as wrapping tiles. New type `BfDescriptionListLayout`.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# bf-donut-chart
|
|
2
|
+
|
|
3
|
+
Donut chart of the parts of a whole, with a legend, tooltip and centre slot
|
|
4
|
+
|
|
5
|
+
`BfDonutChartComponent` from `@bitforgehq/ui/charts` · Data display · since 0.3.1
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Component, computed } from '@angular/core';
|
|
11
|
+
import { BfDonutChartComponent, type BfDonutSlice } from '@bitforgehq/ui/charts';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The bf-donut-chart overview.
|
|
15
|
+
*
|
|
16
|
+
* Live demo of `bf-donut-chart`: a month's spending by category with the total in the centre.
|
|
17
|
+
* Hover a slice, or focus the chart and use the arrow keys; hide a slice in the legend and the
|
|
18
|
+
* others share the rest.
|
|
19
|
+
*/
|
|
20
|
+
@Component({
|
|
21
|
+
selector: 'app-example-donut-chart-overview',
|
|
22
|
+
imports: [BfDonutChartComponent],
|
|
23
|
+
template: `
|
|
24
|
+
<bf-donut-chart label="Spending in October" [slices]="slices" [valueFormat]="francs">
|
|
25
|
+
<span bfSlot="center" class="text-heading text-text">{{ total() }}</span>
|
|
26
|
+
<span bfSlot="center" class="text-caption text-text-muted">October</span>
|
|
27
|
+
</bf-donut-chart>
|
|
28
|
+
`,
|
|
29
|
+
})
|
|
30
|
+
export class DonutChartOverviewExampleComponent {
|
|
31
|
+
readonly slices: readonly BfDonutSlice[] = [
|
|
32
|
+
{ label: 'Rent', value: 1850 },
|
|
33
|
+
{ label: 'Groceries', value: 640 },
|
|
34
|
+
{ label: 'Transport', value: 310 },
|
|
35
|
+
{ label: 'Leisure', value: 280 },
|
|
36
|
+
{ label: 'Other', value: 170 },
|
|
37
|
+
];
|
|
38
|
+
private readonly format = new Intl.NumberFormat('en', {
|
|
39
|
+
style: 'currency',
|
|
40
|
+
currency: 'CHF',
|
|
41
|
+
maximumFractionDigits: 0,
|
|
42
|
+
});
|
|
43
|
+
readonly francs = (value: number): string => this.format.format(value);
|
|
44
|
+
readonly total = computed(() => this.francs(this.slices.reduce((sum, s) => sum + s.value, 0)));
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Overview
|
|
49
|
+
|
|
50
|
+
A donut chart of one set of slices, the parts of a whole (a budget by category, traffic by
|
|
51
|
+
source), drawn in SVG with the chart palette: each slice's angle is its share of the total.
|
|
52
|
+
A legend shows and hides slices (the total follows), a tooltip shows a slice's value and share
|
|
53
|
+
on hover and on keyboard focus (Arrow keys move between the slices and a polite live region
|
|
54
|
+
reads each one), and a Show data table lists them. The `center` slot holds a total or a label
|
|
55
|
+
in the ring's hole. Slices draw in on the first render and on every data change, still under
|
|
56
|
+
reduced motion; under `dir="rtl"` the slices run counter-clockwise.
|
|
57
|
+
|
|
58
|
+
A donut chart shows the parts of one whole: a budget by category, traffic by source, tasks by status. `bf-donut-chart` draws it in SVG from `slices` (each a `label` and a `value`); each slice's angle is its share of the total. A legend shows and hides slices, a tooltip shows a slice's value and share on hover and on keyboard focus, a Show data table lists them, and the `center` slot holds a total in the ring's hole. It lives in `@bitforgehq/ui/charts` (`import { BfDonutChartComponent } from '@bitforgehq/ui/charts'`) and works the same in a desktop web app and in the Capacitor shell.
|
|
59
|
+
|
|
60
|
+
## When to use
|
|
61
|
+
|
|
62
|
+
Use `bf-donut-chart` for the shares of one whole with a few parts (two to six read well). Our charts are themed with the `--color-chart-*` tokens and bring their own legend, tooltip, keyboard reading and data table; bring a chart library (themed with the same tokens) only for a form they do not draw. Use [bf-bar-chart](https://bitforge-ui.web.app/components/bar-chart) instead to compare the parts precisely or when there are many, and [bf-stat](https://bitforge-ui.web.app/components/stat) for a single share ("42 % done").
|
|
63
|
+
|
|
64
|
+
## Centre and thickness
|
|
65
|
+
|
|
66
|
+
Content with `bfSlot="center"` sits in the ring's hole: the total and a caption, such as `1,800 CHF` over `this month`. Keep it short; it does not take pointer events, so hovering the hole never hides the tooltip of a slice. `thickness` sets the ring's width in px (28 by default); a thickness as large as the radius draws a full pie.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { Component } from '@angular/core';
|
|
70
|
+
import { BfDonutChartComponent, type BfDonutSlice } from '@bitforgehq/ui/charts';
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* A thin ring and a pie.
|
|
74
|
+
*
|
|
75
|
+
* `thickness` sets the ring's width: a thin ring leaves room for the centre, a thickness as large
|
|
76
|
+
* as the radius draws a full pie. Tasks by status, the legend above the ring.
|
|
77
|
+
*/
|
|
78
|
+
@Component({
|
|
79
|
+
selector: 'app-example-donut-chart-thickness',
|
|
80
|
+
imports: [BfDonutChartComponent],
|
|
81
|
+
template: `
|
|
82
|
+
<div class="grid w-full grid-cols-[repeat(auto-fit,minmax(min(14rem,100%),1fr))] gap-4">
|
|
83
|
+
<bf-donut-chart label="Tasks by status" legend="top" [thickness]="12" [slices]="tasks">
|
|
84
|
+
<span bfSlot="center" class="text-heading text-text">48</span>
|
|
85
|
+
<span bfSlot="center" class="text-caption text-text-muted">tasks</span>
|
|
86
|
+
</bf-donut-chart>
|
|
87
|
+
<bf-donut-chart
|
|
88
|
+
label="Tasks by status, as a pie"
|
|
89
|
+
legend="top"
|
|
90
|
+
[thickness]="200"
|
|
91
|
+
[slices]="tasks"
|
|
92
|
+
/>
|
|
93
|
+
</div>
|
|
94
|
+
`,
|
|
95
|
+
})
|
|
96
|
+
export class DonutChartThicknessExampleComponent {
|
|
97
|
+
readonly tasks: readonly BfDonutSlice[] = [
|
|
98
|
+
{ label: 'Done', value: 27 },
|
|
99
|
+
{ label: 'In progress', value: 13 },
|
|
100
|
+
{ label: 'Blocked', value: 8 },
|
|
101
|
+
];
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Data and formatting
|
|
106
|
+
|
|
107
|
+
Slices run clockwise from the top in their order (counter-clockwise under `dir="rtl"`), with a 2 px gap between them; a slice of zero or less draws nothing, but stays in the legend and the table. Hiding a slice in the legend removes it from the total, so the other shares grow. `valueFormat` formats the values in the tooltip, the announcement and the table; unset, values use `Intl.NumberFormat` in the document's language, and shares are whole percentages. The slices draw in along the ring on the first render and whenever `slices` change. `height` sets the plot's height in px (220 by default); the ring fits the smaller of it and the container's width.
|
|
108
|
+
|
|
109
|
+
## Desktop
|
|
110
|
+
|
|
111
|
+
Under a mouse, hovering a slice thickens it and shows its tooltip; the hole and the space around the ring show none. The plot is one stop in the tab order, with the focus ring on keyboard focus: focusing it shows the first slice. Under a coarse pointer (touch) a tap shows a slice's tooltip, and the legend buttons and the Show data button are at least 44 px tall. Inside `provideBfShell()` it renders and behaves the same.
|
|
112
|
+
|
|
113
|
+
## Theming
|
|
114
|
+
|
|
115
|
+
- Slices: `--color-chart-1` … `--color-chart-8` in order (`stroke-chart-n`); the ring's track: `chart-grid`.
|
|
116
|
+
- Tooltip, legend and data table: as in [bf-line-chart](https://bitforge-ui.web.app/components/line-chart).
|
|
117
|
+
- Motion: `--animate-chart-draw` along each slice; the active slice thickens over 150 ms; none under `prefers-reduced-motion`.
|
|
118
|
+
|
|
119
|
+
## Accessibility
|
|
120
|
+
|
|
121
|
+
The chart is a native `figure` named by `label` (else the `bf-chart-card` title, else the `chart` label); the SVG is hidden from assistive technology, and the centre slot's text is read as part of the figure. The plot is a focusable `role="group"` named by the `chartValues` label: the arrow keys move between the slices and a polite live region reads each one with its share ("Rent: 900 CHF (50%)"). The legend is a group of toggle buttons (`aria-pressed`); the Show data button (`aria-expanded`) shows the slices as a native `table` (`chartCategory` and `chartValue` headers). Every slice colour is ≥ 3:1 against `surface` and `bg`, and the legend names each one.
|
|
122
|
+
|
|
123
|
+
### Keyboard
|
|
124
|
+
|
|
125
|
+
| Key | Action |
|
|
126
|
+
| ------------------------------------------------ | ------------------------------------------------------------------------------------ |
|
|
127
|
+
| <kbd>Tab</kbd> / <kbd>Shift</kbd>+<kbd>Tab</kbd> | Moves through the plot, the legend buttons and the Show data button |
|
|
128
|
+
| <kbd>ArrowRight</kbd> | Moves to the next slice and reads it (the previous one under `dir="rtl"`) |
|
|
129
|
+
| <kbd>ArrowLeft</kbd> | Moves to the previous slice and reads it (the next one under `dir="rtl"`) |
|
|
130
|
+
| <kbd>Home</kbd> / <kbd>End</kbd> | Moves to the first / last slice |
|
|
131
|
+
| <kbd>Escape</kbd> | Hides the tooltip |
|
|
132
|
+
| <kbd>Enter</kbd> / <kbd>Space</kbd> | On a legend button, shows or hides its slice; on Show data, shows or hides the table |
|
|
133
|
+
|
|
134
|
+
## Inputs
|
|
135
|
+
|
|
136
|
+
| Name | Type | Default | Description |
|
|
137
|
+
| ------------- | --------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
138
|
+
| `slices` | `readonly BfDonutSlice[]` | required | The slices, in order clockwise from the top. |
|
|
139
|
+
| `label` | `string` | `''` | The chart's accessible name; empty falls back to the `bf-chart-card` title, then to `provideBfLabels()`'s `chart` ("Chart"). |
|
|
140
|
+
| `height` | `number` | `220` | The plot's height in px; the ring fits the smaller of it and the container's width. |
|
|
141
|
+
| `thickness` | `number` | `28` | The ring's thickness in px (at most the radius, a full pie). |
|
|
142
|
+
| `valueFormat` | `BfChartValueFormat \| undefined` | `undefined` | Formats the values in the tooltip, the announcements and the table; unset uses `Intl.NumberFormat` in the document's language. |
|
|
143
|
+
| `legend` | `BfChartLegendPosition \| undefined` (`'top' \| 'bottom' \| 'none' \| undefined`) | `undefined` | Where the legend goes; unset follows the `bf-chart-card`, else `bottom`. A single slice draws no legend. |
|
|
144
|
+
|
|
145
|
+
## Slots
|
|
146
|
+
|
|
147
|
+
- `center`: Content in the ring's hole, such as the total and its label.
|
|
148
|
+
|
|
149
|
+
## Notes
|
|
150
|
+
|
|
151
|
+
### Do
|
|
152
|
+
|
|
153
|
+
- Order the slices from largest to smallest, starting at the top.
|
|
154
|
+
- Put the total in the `center` slot, so the shares have a whole to refer to.
|
|
155
|
+
|
|
156
|
+
### Don't
|
|
157
|
+
|
|
158
|
+
- Don't use a donut for more than about six slices or for slices of nearly equal size; use a bar chart.
|
|
159
|
+
- Don't use it for values that do not add up to a whole.
|
|
160
|
+
|
|
161
|
+
## Migration notes
|
|
162
|
+
|
|
163
|
+
### 0.3.1
|
|
164
|
+
|
|
165
|
+
New `bf-donut-chart` in `@bitforgehq/ui/charts`: `slices` (`BfDonutSlice`: `label`, `value`) as
|
|
166
|
+
the parts of a whole, with a `thickness`, a `center` slot for a total, a legend that hides slices
|
|
167
|
+
(the shares follow), a tooltip with each slice's value and share, keyboard reading and a data
|
|
168
|
+
table. Slices draw in along the ring, not under reduced motion, and run counter-clockwise under
|
|
169
|
+
`dir="rtl"`.
|
package/ai/components/header.md
CHANGED
|
@@ -103,7 +103,7 @@ the collapse is pure CSS and scrolling never schedules Angular change detection.
|
|
|
103
103
|
|
|
104
104
|
## When to use
|
|
105
105
|
|
|
106
|
-
Use `bf-header` at the top of every `bf-page` in the Capacitor shell: the bar with its start and end actions and the collapsing large title. Use
|
|
106
|
+
Use `bf-header` at the top of every `bf-page` in the Capacitor shell: the bar with its start and end actions and the collapsing large title. Use [bf-page-header](https://bitforge-ui.web.app/components/page-header) instead on a desktop web page, and [bf-back-button](https://bitforge-ui.web.app/components/back-button) in its `start` slot on a pushed page.
|
|
107
107
|
|
|
108
108
|
## Basic usage
|
|
109
109
|
|
|
@@ -608,7 +608,67 @@ inside one.
|
|
|
608
608
|
|
|
609
609
|
## Desktop
|
|
610
610
|
|
|
611
|
-
`bf-header` is part of the Capacitor shell (`provideBfShell()`), shaped like an iOS or Material app bar. On a desktop web page
|
|
611
|
+
`bf-header` is part of the Capacitor shell (`provideBfShell()`), shaped like an iOS or Material app bar. On a desktop web page use [bf-page-header](https://bitforge-ui.web.app/components/page-header): the page's one `h1` (`title`) with an optional `subtitle`, badges in `meta`, and the actions in `actions` (the main action as a primary [bf-button](https://bitforge-ui.web.app/components/button), secondary ones as `ghost` or `outline` buttons, the rest in an icon-only [bf-menu-button](https://bitforge-ui.web.app/components/menu-button) labelled "More actions"); the actions wrap under the title in a narrow window. On a nested page, put a [bf-breadcrumb](https://bitforge-ui.web.app/components/breadcrumb) in its `breadcrumb` slot, and a [bf-toolbar](https://bitforge-ui.web.app/components/toolbar) under it for search and filters. The two are siblings rather than one shell-aware widget: the large title and the scroll-under surface are phone patterns that depend on `bf-content`.
|
|
612
|
+
|
|
613
|
+
```ts
|
|
614
|
+
import { Component, signal } from '@angular/core';
|
|
615
|
+
import { BfButtonComponent, BfPageHeaderComponent } from '@bitforgehq/ui';
|
|
616
|
+
import { BfIconComponent } from '@bitforgehq/ui/icons';
|
|
617
|
+
import {
|
|
618
|
+
BfMenuButtonComponent,
|
|
619
|
+
BfMenuComponent,
|
|
620
|
+
BfMenuItemDirective,
|
|
621
|
+
} from '@bitforgehq/ui/overlay';
|
|
622
|
+
import { Ellipsis, Plus } from 'lucide';
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* The desktop replacement for a header: a bf-page-header.
|
|
626
|
+
*
|
|
627
|
+
* The page's `h1` with a subtitle, and its actions in the `actions` slot: a ghost button, the
|
|
628
|
+
* primary action and a menu button for the rest; the actions wrap under the title in a narrow
|
|
629
|
+
* window.
|
|
630
|
+
*/
|
|
631
|
+
@Component({
|
|
632
|
+
selector: 'app-example-header-desktop-header',
|
|
633
|
+
imports: [
|
|
634
|
+
BfButtonComponent,
|
|
635
|
+
BfIconComponent,
|
|
636
|
+
BfMenuButtonComponent,
|
|
637
|
+
BfMenuComponent,
|
|
638
|
+
BfMenuItemDirective,
|
|
639
|
+
BfPageHeaderComponent,
|
|
640
|
+
],
|
|
641
|
+
template: `
|
|
642
|
+
<bf-page-header title="Atlas rebrand" subtitle="12 of 18 tasks done · due Friday">
|
|
643
|
+
<bf-button bfSlot="actions" variant="ghost" (clicked)="status.set('Shared.')"
|
|
644
|
+
>Share</bf-button
|
|
645
|
+
>
|
|
646
|
+
<bf-button bfSlot="actions" (clicked)="status.set('New task.')">
|
|
647
|
+
<bf-icon bfSlot="icon-start" [icon]="plus" />
|
|
648
|
+
New task
|
|
649
|
+
</bf-button>
|
|
650
|
+
<bf-menu-button bfSlot="actions" [menu]="more" iconOnly label="More actions" variant="text">
|
|
651
|
+
<bf-icon [icon]="ellipsis" />
|
|
652
|
+
</bf-menu-button>
|
|
653
|
+
</bf-page-header>
|
|
654
|
+
<p aria-live="polite" class="text-caption text-text-muted mt-3">{{ status() }}</p>
|
|
655
|
+
|
|
656
|
+
<ng-template #more>
|
|
657
|
+
<bf-menu>
|
|
658
|
+
<button bfMenuItem (triggered)="status.set('Renamed.')">Rename</button>
|
|
659
|
+
<button bfMenuItem (triggered)="status.set('Archived.')">Archive</button>
|
|
660
|
+
</bf-menu>
|
|
661
|
+
</ng-template>
|
|
662
|
+
`,
|
|
663
|
+
})
|
|
664
|
+
export class HeaderDesktopHeaderExampleComponent {
|
|
665
|
+
protected readonly plus = Plus;
|
|
666
|
+
protected readonly ellipsis = Ellipsis;
|
|
667
|
+
protected readonly status = signal('');
|
|
668
|
+
}
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
Under the shell, a browser window shorter than 500 px gets the compact bar (no large title), as a phone in landscape does.
|
|
612
672
|
|
|
613
673
|
## Theming
|
|
614
674
|
|
|
@@ -688,6 +748,11 @@ The title is not in the tab order; after a push, `bf-stack-outlet` focuses it wi
|
|
|
688
748
|
|
|
689
749
|
## Migration notes
|
|
690
750
|
|
|
751
|
+
### 0.3.1
|
|
752
|
+
|
|
753
|
+
The `## Desktop` docs and When to use name the desktop replacement, `bf-page-header` (with
|
|
754
|
+
`bf-breadcrumb` and `bf-toolbar`), with an example. No code change.
|
|
755
|
+
|
|
691
756
|
### 0.3.0
|
|
692
757
|
|
|
693
758
|
JSDoc of `header.component.ts` for the API reference: `@slot` docs for `start`, `default`, `end`. No
|