@bitforgehq/ui 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/README.md +4 -4
  3. package/ai/MANIFEST.index.json +36 -0
  4. package/ai/MANIFEST.json +436 -24
  5. package/ai/REFERENCE.index.json +35 -0
  6. package/ai/REFERENCE.json +202 -10
  7. package/ai/UI_GUIDE.md +25 -4
  8. package/ai/components/app-frame.md +14 -7
  9. package/ai/components/badge.md +39 -2
  10. package/ai/components/header.md +9 -0
  11. package/ai/components/list-item.md +105 -9
  12. package/ai/components/step.md +112 -0
  13. package/ai/components/steps.md +124 -0
  14. package/ai/components/table.md +119 -5
  15. package/ai/components/timeline-event.md +144 -0
  16. package/ai/components/timeline.md +201 -0
  17. package/ai/components/toggle.md +11 -1
  18. package/ai/reference/bf-action-directive.md +3 -1
  19. package/ai/reference/bf-badge-emphasis.md +27 -0
  20. package/ai/reference/bf-labels.md +2 -0
  21. package/ai/reference/bf-select-harness.md +4 -0
  22. package/ai/reference/bf-step-heading-level.md +28 -0
  23. package/ai/reference/bf-table-align.md +1 -1
  24. package/ai/reference/bf-table-column-align.md +33 -0
  25. package/ai/reference/bf-table-column.md +7 -7
  26. package/ai/reference/bf-table-harness.md +18 -0
  27. package/ai/reference/bf-timeline-tone.md +31 -0
  28. package/ai/reference/bf-toggle-harness.md +55 -0
  29. package/ai/reference/provide-bf-labels.md +2 -2
  30. package/dark-ink.css +124 -0
  31. package/fesm2022/bitforgehq-ui-mobile.mjs +13 -3
  32. package/fesm2022/bitforgehq-ui-mobile.mjs.map +1 -1
  33. package/fesm2022/bitforgehq-ui-testing.mjs +55 -2
  34. package/fesm2022/bitforgehq-ui-testing.mjs.map +1 -1
  35. package/fesm2022/bitforgehq-ui.mjs +714 -46
  36. package/fesm2022/bitforgehq-ui.mjs.map +1 -1
  37. package/llms-full.txt +1128 -26
  38. package/llms.txt +9 -0
  39. package/package.json +2 -1
  40. package/theme.css +37 -0
  41. package/types/bitforgehq-ui-testing.d.ts +90 -1
  42. package/types/bitforgehq-ui.d.ts +306 -18
@@ -0,0 +1,144 @@
1
+ # bf-timeline-event
2
+
3
+ One timeline event with a coloured marker, its text, actor and time
4
+
5
+ `BfTimelineEventComponent` from `@bitforgehq/ui` · Data display · since 0.4.0
6
+
7
+ ## Example
8
+
9
+ ```ts
10
+ import { Component } from '@angular/core';
11
+ import { RouterLink } from '@angular/router';
12
+ import { BfTimelineComponent, BfTimelineEventComponent } from '@bitforgehq/ui';
13
+
14
+ /**
15
+ * The bf-timeline-event overview.
16
+ *
17
+ * Live demo of `bf-timeline-event`: one event per tone in a `bf-timeline`, with and without an
18
+ * actor, one with a link in its text and one with a relative `timeText`.
19
+ */
20
+ @Component({
21
+ selector: 'app-example-timeline-event-overview',
22
+ imports: [RouterLink, BfTimelineComponent, BfTimelineEventComponent],
23
+ template: `
24
+ <bf-timeline label="Event tones" class="max-w-xl">
25
+ <bf-timeline-event actor="Lena Meier" time="2026-10-28T15:40:00Z" tone="primary">
26
+ Opened
27
+ <a routerLink="/components/timeline" fragment="links-in-events">CVE-2026-1234</a>
28
+ </bf-timeline-event>
29
+ <bf-timeline-event actor="CI" time="2026-10-28T15:10:00Z" tone="success">
30
+ All checks passed
31
+ </bf-timeline-event>
32
+ <bf-timeline-event actor="Dependency bot" time="2026-10-28T14:00:00Z" tone="warning">
33
+ Found an outdated base image
34
+ </bf-timeline-event>
35
+ <bf-timeline-event actor="CI" time="2026-10-28T13:05:00Z" tone="danger">
36
+ CI failed on the security scan
37
+ </bf-timeline-event>
38
+ <bf-timeline-event time="2026-10-28T12:00:00Z" timeText="4 hours ago" tone="info">
39
+ A new advisory was published
40
+ </bf-timeline-event>
41
+ <bf-timeline-event actor="Jonas Keller" time="2026-10-27T16:02:00Z">
42
+ Assigned the finding to Lena Meier
43
+ </bf-timeline-event>
44
+ </bf-timeline>
45
+ `,
46
+ })
47
+ export class TimelineEventOverviewExampleComponent {}
48
+ ```
49
+
50
+ ## Overview
51
+
52
+ One event of a `bf-timeline`: a marker coloured by `tone`, the event text (the default slot,
53
+ which may hold links), then who did it (`actor`) and when (`time`, in a `time` element).
54
+
55
+ One event of a [`bf-timeline`](https://bitforge-ui.web.app/components/timeline): a marker coloured by `tone`, the event text from the default slot, then a meta line with `actor` and `time`. Place events in a `bf-timeline`, which gives them the list semantics and the time format; the line between the markers ends at the last event.
56
+
57
+ ## When to use
58
+
59
+ Use `bf-timeline-event` for each dated entry of a `bf-timeline`: a change, a comment, a CI run. Use [bf-list-item](https://bitforge-ui.web.app/components/list-item) instead for a row the user opens or acts on.
60
+
61
+ ## Basic usage
62
+
63
+ `actor`, `time` (a `Date` or an ISO 8601 string) and `tone` are inputs; the text is the content and may hold links, which take the link style. `timeText` replaces the formatted time with your own text while the `datetime` keeps the exact value. `bfSlot="end"` holds a small action, at the inline end on a wide timeline and below the text on a narrow one.
64
+
65
+ ```ts
66
+ import { Component } from '@angular/core';
67
+ import { BfTimelineComponent, BfTimelineEventComponent } from '@bitforgehq/ui';
68
+
69
+ /**
70
+ * An event's actor, time and tone.
71
+ *
72
+ * Two events of a CVE side panel: one by a person with an exact time, one by a bot with a relative
73
+ * `timeText` whose `datetime` keeps the exact value.
74
+ */
75
+ @Component({
76
+ selector: 'app-example-timeline-event-basic',
77
+ imports: [BfTimelineComponent, BfTimelineEventComponent],
78
+ template: `
79
+ <bf-timeline label="CVE history" class="max-w-sm">
80
+ <bf-timeline-event actor="Lena Meier" time="2026-10-28T15:40:00Z" tone="warning">
81
+ Accepted the risk until the next release
82
+ </bf-timeline-event>
83
+ <bf-timeline-event
84
+ actor="Advisory bot"
85
+ time="2026-10-28T10:00:00Z"
86
+ timeText="6 hours ago"
87
+ tone="info"
88
+ >
89
+ Imported the advisory
90
+ </bf-timeline-event>
91
+ </bf-timeline>
92
+ `,
93
+ })
94
+ export class TimelineEventBasicExampleComponent {}
95
+ ```
96
+
97
+ ## Desktop
98
+
99
+ An event has no hover and no focus stop of its own; only the links in its text and the controls in its `end` slot are interactive. It renders the same inside `provideBfShell()`.
100
+
101
+ ## Theming
102
+
103
+ - Marker: `text-subtle`, `primary`, `success`, `warning`, `danger` or `info`; `CanvasText` under forced colours. Line: `border`.
104
+ - Text `text-body` in `text`, links `primary-text`; meta line `text-caption` in `text-muted`.
105
+
106
+ ## Accessibility
107
+
108
+ Inside a `bf-timeline` the event is a `listitem`; on its own it has no role. The marker is `aria-hidden`; the time is a `time` element with an ISO `datetime`, and the separator between actor and time is hidden from assistive technology.
109
+
110
+ ## Inputs
111
+
112
+ | Name | Type | Default | Description |
113
+ | ---------- | ------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------ |
114
+ | `actor` | `string` | `''` | Who did it, such as a person or a bot; empty for a system event. |
115
+ | `time` | `Date \| string \| null` | `null` | When it happened: a Date or an ISO 8601 string; empty or invalid shows no time. |
116
+ | `timeText` | `string` | `''` | Shown in place of the formatted time, such as "vor 2 Std."; the `time` element's `datetime` keeps the exact value. |
117
+ | `tone` | `BfTimelineTone` (`'neutral' \| 'primary' \| 'success' \| 'warning' \| 'danger' \| 'info'`) | `'neutral'` | The marker's colour. |
118
+
119
+ ## Slots
120
+
121
+ - `default`: The event text; links in it take the link style.
122
+ - `end`: Content at the inline end on a wide timeline and below the text on a narrow one, such as a button.
123
+
124
+ ## Notes
125
+
126
+ ### Do
127
+
128
+ - Write the text as what happened ("Assigned to Lena Meier"), and link the object it names.
129
+
130
+ ### Don't
131
+
132
+ - Don't put more than one small action in the `end` slot; open the details elsewhere.
133
+
134
+ ## Migration notes
135
+
136
+ ### 0.4.0
137
+
138
+ New: `bf-timeline-event`, one event of a `bf-timeline`: a 10 px marker coloured by `tone`
139
+ (`neutral`, `primary`, `success`, `warning`, `danger`, `info`; new type `BfTimelineTone`) on a
140
+ `border` line that ends at the last event, the event text in the default slot (links in it take
141
+ the link style), then `actor` and `time` (a `Date` or an ISO 8601 string, in a `time` element;
142
+ `timeText` shows a relative text while `datetime` keeps the exact value; an invalid time shows
143
+ nothing). A `bfSlot="end"` action sits at the inline end, or under the text once the event is
144
+ narrow.
@@ -0,0 +1,201 @@
1
+ # bf-timeline
2
+
3
+ Dated list of events with who did what and when, on a vertical line
4
+
5
+ `BfTimelineComponent` from `@bitforgehq/ui` · Data display · since 0.4.0
6
+
7
+ ## Example
8
+
9
+ ```ts
10
+ import { Component } from '@angular/core';
11
+ import { RouterLink } from '@angular/router';
12
+ import { BfTimelineComponent, BfTimelineEventComponent } from '@bitforgehq/ui';
13
+
14
+ /**
15
+ * The bf-timeline overview.
16
+ *
17
+ * Live demo of `bf-timeline`: the history of a security finding, newest first. A system event has
18
+ * no actor, the pull request is a link in the event text, the failed CI run is `danger` and the
19
+ * fix `success`.
20
+ */
21
+ @Component({
22
+ selector: 'app-example-timeline-overview',
23
+ imports: [RouterLink, BfTimelineComponent, BfTimelineEventComponent],
24
+ template: `
25
+ <bf-timeline label="Finding history" class="max-w-xl">
26
+ <bf-timeline-event actor="Lena Meier" time="2026-10-28T15:40:00Z" tone="success">
27
+ Marked the finding as fixed
28
+ </bf-timeline-event>
29
+ <bf-timeline-event actor="CI" time="2026-10-28T13:05:00Z" tone="danger">
30
+ CI failed on the security scan
31
+ </bf-timeline-event>
32
+ <bf-timeline-event actor="Jonas Keller" time="2026-10-28T11:20:00Z" tone="primary">
33
+ Linked
34
+ <a routerLink="." fragment="links-in-events">PR #123</a>
35
+ to the finding
36
+ </bf-timeline-event>
37
+ <bf-timeline-event actor="Jonas Keller" time="2026-10-27T16:02:00Z">
38
+ Assigned the finding to Lena Meier
39
+ </bf-timeline-event>
40
+ <bf-timeline-event time="2026-10-27T08:14:00Z">
41
+ Created by the nightly dependency scan
42
+ </bf-timeline-event>
43
+ </bf-timeline>
44
+ `,
45
+ })
46
+ export class TimelineOverviewExampleComponent {}
47
+ ```
48
+
49
+ ## Overview
50
+
51
+ A dated history of events, newest first or oldest first as the consumer orders them: who did
52
+ what and when, each event a `bf-timeline-event` with a marker on a vertical line.
53
+
54
+ A timeline shows the history of one thing as dated events: who did what, and when. Each event is a [`bf-timeline-event`](https://bitforge-ui.web.app/components/timeline-event) with a coloured marker on a vertical line, its text (which may link the objects it names), then the actor and the time. The timeline shows the events in the order you give them, newest first or oldest first; it never sorts. It works the same in a desktop web app, a narrow side panel and the Capacitor shell.
55
+
56
+ ## When to use
57
+
58
+ Use `bf-timeline` for a record's history or an audit trail: a finding that was created, assigned, linked to a pull request and fixed; the changes in a CVE side panel; who changed a setting. Use [bf-list](https://bitforge-ui.web.app/components/list) instead for items the user opens or acts on, and for navigation; a timeline is not a stepper through a process either, nor a feed the user scrolls for new items. For the details of one record, use a [bf-description-list](https://bitforge-ui.web.app/components/description-list).
59
+
60
+ ## Events and tones
61
+
62
+ `actor` names who did it (leave it empty for a system event), `time` says when (a `Date` or an ISO 8601 string), and the content is the event text. `tone` colours the marker: `neutral` (the default) for routine events, `primary` for the current or most important one, `success` (fixed, merged), `warning`, `danger` (CI failed, a regression) and `info`. The colour only supports the text, so say what happened in words ("CI failed"), never by the colour alone. The line runs from each marker to the next and ends at the last event.
63
+
64
+ ## Links in events
65
+
66
+ The event text is the default slot, so the objects it names can be links: a pull request, a repository, a CVE. Put a plain `<a href>` (or `<a routerLink>`) inline in the text; the event styles every link in its text in `primary-text`, underlined, with a thicker underline on hover and the focus ring on keyboard focus. Keep the link text the object's name ("PR #123"), not "here".
67
+
68
+ ## Time format
69
+
70
+ The time is formatted with `Intl.DateTimeFormat` in the app's `LOCALE_ID`: a medium date and a short time by default (`28 Oct 2026, 14:30` in `en-GB`, `28.10.2026, 14:30` in `de-CH`), in the browser's time zone. `timeFormat` on the timeline takes any `Intl.DateTimeFormatOptions` for all its events (`{ dateStyle: 'short' }`, or a `timeZone`), and `locale` overrides the language for one timeline. `timeText` on an event shows your own text in place of the formatted time, such as a relative "vor 2 Std."; the `time` element's `datetime` keeps the exact value. An empty or invalid `time` shows no time, and a locale or options the browser refuses fall back to the defaults, so a bad value never throws.
71
+
72
+ ## Audit trail
73
+
74
+ An audit trail is actor-heavy: every event names a person or a bot. The `end` slot holds a small action for one event, such as a Show diff button: it sits at the inline end while the timeline is wide, and wraps under the text in a narrow side panel or on a phone (once the text would get narrower than 16rem). It takes no space while empty.
75
+
76
+ ```ts
77
+ import { Component, signal } from '@angular/core';
78
+ import { BfButtonComponent, BfTimelineComponent, BfTimelineEventComponent } from '@bitforgehq/ui';
79
+
80
+ interface AuditEntry {
81
+ id: string;
82
+ actor: string;
83
+ action: string;
84
+ time: string;
85
+ ago: string;
86
+ diff: boolean;
87
+ }
88
+
89
+ const ENTRIES: readonly AuditEntry[] = [
90
+ {
91
+ id: 'severity',
92
+ actor: 'Lena Meier',
93
+ action: 'Raised the severity from Medium to High',
94
+ time: '2026-10-28T14:10:00Z',
95
+ ago: '2 hours ago',
96
+ diff: true,
97
+ },
98
+ {
99
+ id: 'policy',
100
+ actor: 'Policy bot',
101
+ action: 'Applied the "Critical CVEs block releases" policy',
102
+ time: '2026-10-28T09:30:00Z',
103
+ ago: '7 hours ago',
104
+ diff: true,
105
+ },
106
+ {
107
+ id: 'owner',
108
+ actor: 'Jonas Keller',
109
+ action: 'Set the owner to the Platform team',
110
+ time: '2026-10-27T16:45:00Z',
111
+ ago: 'Yesterday',
112
+ diff: false,
113
+ },
114
+ ];
115
+
116
+ /**
117
+ * An audit trail with relative times and an action per event.
118
+ *
119
+ * Every event names its actor, `timeText` shows a relative time while `datetime` keeps the exact
120
+ * one, and the `end` slot holds a Show diff button: at the inline end while the timeline is wide,
121
+ * under the text in a narrow panel.
122
+ */
123
+ @Component({
124
+ selector: 'app-example-timeline-audit',
125
+ imports: [BfButtonComponent, BfTimelineComponent, BfTimelineEventComponent],
126
+ template: `
127
+ <div class="flex max-w-xl flex-col gap-3">
128
+ <bf-timeline label="Audit trail">
129
+ @for (entry of entries; track entry.id) {
130
+ <bf-timeline-event [actor]="entry.actor" [time]="entry.time" [timeText]="entry.ago">
131
+ {{ entry.action }}
132
+ @if (entry.diff) {
133
+ <bf-button bfSlot="end" variant="outline" size="sm" (clicked)="showDiff(entry)">
134
+ Show diff
135
+ </bf-button>
136
+ }
137
+ </bf-timeline-event>
138
+ }
139
+ </bf-timeline>
140
+ <p data-status aria-live="polite" class="text-caption text-text-muted">{{ status() }}</p>
141
+ </div>
142
+ `,
143
+ })
144
+ export class TimelineAuditExampleComponent {
145
+ readonly entries = ENTRIES;
146
+ readonly status = signal('No diff open.');
147
+
148
+ /** A real app would open the change in a side panel. */
149
+ showDiff(entry: AuditEntry): void {
150
+ this.status.set(`Diff of "${entry.action}" by ${entry.actor}.`);
151
+ }
152
+ }
153
+ ```
154
+
155
+ ## Desktop
156
+
157
+ The timeline itself is not interactive: no hover, no pointer cursor, no focus stop. Only the links in the event text and the controls in an `end` slot take focus, with their own hover and focus ring. Its spacing does not follow `provideBfDefaults()`: the events keep one rhythm at every density, and it has no `size`. Inside `provideBfShell()` it renders and behaves the same; the `end` slot's buttons bring their own 44 px touch height.
158
+
159
+ ## Theming
160
+
161
+ - Marker: a 10 px dot (`rounded-control`) in `text-subtle` (neutral), `primary`, `success`, `warning`, `danger` or `info`; `CanvasText` under forced colours.
162
+ - Line: a 1 px `border` line from marker to marker.
163
+ - Text: `text-body` in `text`; links `primary-text`, underlined, `ring` on keyboard focus. Meta line: `text-caption` in `text-muted`.
164
+ - Spacing: 12 px between the marker and the text, 20 px between events.
165
+
166
+ ## Accessibility
167
+
168
+ The timeline is a list (`role="list"`, named by `label` through `aria-label`) and each event inside it a `listitem`, so a screen reader announces the number of events and the position of each. An event outside a `bf-timeline` claims no role. The marker and the line are `aria-hidden`; the tone is decoration, so the text must say what happened. The time is a `time` element whose `datetime` is the ISO value, and the separator between actor and time is hidden from assistive technology. Links and `end` slot controls are native elements in reading order.
169
+
170
+ ## Inputs
171
+
172
+ | Name | Type | Default | Description |
173
+ | ------------ | ---------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
174
+ | `label` | `string` | `''` | The list's accessible name, such as "History"; empty leaves the list unnamed (a visible heading above it already names the section). |
175
+ | `timeFormat` | `Intl.DateTimeFormatOptions` | `TIMELINE_TIME_FORMAT` | `Intl.DateTimeFormat` options of every event's time; by default a medium date and a short time (`dateStyle: 'medium'`, `timeStyle: 'short'`). |
176
+ | `locale` | `string` | `''` | BCP 47 locale of the times, such as `de-CH`; empty follows the app's `LOCALE_ID`. |
177
+
178
+ ## Slots
179
+
180
+ - `default`: The events, each a `bf-timeline-event`, in the order to show them.
181
+
182
+ ## Notes
183
+
184
+ ### Do
185
+
186
+ - Give the timeline a `label` when no visible heading names it, and keep one order (newest first) across the app.
187
+ - Name the actor and the object in every event; link the object.
188
+
189
+ ### Don't
190
+
191
+ - Don't use a timeline for navigation or for steps the user still has to take.
192
+ - Don't carry meaning in the tone alone; say "CI failed", not just a red dot.
193
+
194
+ ## Migration notes
195
+
196
+ ### 0.4.0
197
+
198
+ New: `bf-timeline`, a dated history of events (who did what, and when) for a record's history
199
+ or an audit trail, in both shells. A `role="list"` named by `label`, in the order the consumer
200
+ gives (it never sorts); each event's time is formatted with `Intl.DateTimeFormat` in the app's
201
+ `LOCALE_ID` (`timeFormat`, default a medium date and a short time; `locale` overrides it).
@@ -130,9 +130,11 @@ export class ToggleListRowExampleComponent {
130
130
  }
131
131
  ```
132
132
 
133
+ In a table of switches (a settings matrix: alert kinds by channel), each cell's toggle is named after its column and row with `ariaLabel`; see [bf-table](https://bitforge-ui.web.app/components/table)'s Toggle cells.
134
+
133
135
  ## Sizes
134
136
 
135
- `sm` (32 px row, 24×40 track), `md` (default, 40 px row, 28×48 track), `lg` (48 px row, 32×56 track). Unset, `size` follows `provideBfDefaults()`'s `controlSize`, `md` by default (`provideBfDefaults({ size: 'lg' })` enlarges every control of a Capacitor app; `{ size: 'sm' }` in a component's `providers` makes a dense sub-tree). Under a fine pointer the row is the hit area (32 px and up, above the 24 px of WCAG 2.5.8); under a coarse pointer (touch) `sm` and `md` rows grow to 44 px. The knob travels to the inline end, so it moves left under `dir="rtl"`.
137
+ `sm` (32 px row, 24×40 track), `md` (default, 40 px row, 28×48 track), `lg` (48 px row, 32×56 track). Unset, `size` follows `provideBfDefaults()`'s `controlSize`, `md` by default (`provideBfDefaults({ size: 'lg' })` enlarges every control of a Capacitor app; `{ size: 'sm' }` in a component's `providers` makes a dense sub-tree). Under a fine pointer the row is the hit area (32 px and up, above the 24 px of WCAG 2.5.8); under a coarse pointer (touch) `sm` and `md` rows grow to 44 px, and a label-less `sm` switch (40 px wide) also takes a 44 px width, its track centred. The knob travels to the inline end, so it moves left under `dir="rtl"`.
136
138
 
137
139
  ```ts
138
140
  import { Component, signal } from '@angular/core';
@@ -325,6 +327,14 @@ Focuses the native switch; Signal Forms calls it from `focusBoundControl()`.
325
327
 
326
328
  ## Migration notes
327
329
 
330
+ ### 0.4.0
331
+
332
+ A label-less `sm` toggle (a table cell) takes a 44 px min-width under a coarse pointer, its track
333
+ centred, so its touch target is 44 × 44 px (it was 40 px wide). Nothing changes under a fine
334
+ pointer or for `md` and `lg`. `@bitforgehq/ui/testing`: new `BfToggleHarness` (`with({ label })`
335
+ by the switch's computed name, `getLabel()`, `isChecked()`, `isDisabled()`, `isReadonly()`,
336
+ `toggle()`, `check()`, `uncheck()`, `getErrorText()`).
337
+
328
338
  ### 0.3.0
329
339
 
330
340
  New `ariaLabelledby` input: the id of the element that names the switch when no visible `label`
@@ -12,7 +12,9 @@ exposed: the heading stays a heading and the accessible name is the title alone.
12
12
  with the nearest card or row, which then draws the pointer, the hover and, while the action has
13
13
  keyboard focus, the focus ring; a card is never lit by the actions of rows nested in it. Give
14
14
  secondary controls inside the surface `class="relative z-1"` so they stay clickable above the
15
- stretched area.
15
+ stretched area. When the surface marks a state that belongs in the name (an `unread` list
16
+ row), the directive names the element `aria-labelledby="<state id> <own id>"`, so the link reads
17
+ "Unread, Account", and restores the element's own `aria-labelledby` when the state goes.
16
18
 
17
19
  ```ts
18
20
  import { BfActionDirective } from '@bitforgehq/ui';
@@ -0,0 +1,27 @@
1
+ # BfBadgeEmphasis
2
+
3
+ The two badge emphases, the soft tint or the solid strong fill
4
+
5
+ Type from `@bitforgehq/ui` · since 0.4.0
6
+
7
+ How loud a `bf-badge` is: `soft`, a pale tint with tinted text (the default), or `strong`, a
8
+ solid fill with contrasting text for the one state that must stand out, such as "Critical".
9
+
10
+ ```ts
11
+ import { type BfBadgeEmphasis } from '@bitforgehq/ui';
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```ts
17
+ type BfBadgeEmphasis = 'soft' | 'strong'
18
+ ```
19
+
20
+ ## Values
21
+
22
+ - `soft`
23
+ - `strong`
24
+
25
+ ## Used by
26
+
27
+ - [bf-badge](../components/badge.md)
@@ -33,6 +33,7 @@ import { type BfLabels } from '@bitforgehq/ui';
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
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. |
36
37
  | `tableSortAscending` | `(column: string) => string` | `` (column) => `${column}, ascending` `` | A stacked bf-table's sort option for a column in ascending order. |
37
38
  | `tableSortDescending` | `(column: string) => string` | `` (column) => `${column}, descending` `` | A stacked bf-table's sort option for a column in descending order. |
38
39
  | `theme` | `string` | `'Theme'` | bf-theme-switch's and bf-theme-menu-button's name without a label. |
@@ -84,6 +85,7 @@ import { type BfLabels } from '@bitforgehq/ui';
84
85
  | `chartValue` | `string` | `'Value'` | The value column header of a bf-donut-chart's data table. |
85
86
  | `chartEmpty` | `string` | `'No data to show'` | bf-chart-card's text when it has no data and no `empty` slot. |
86
87
  | `chartError` | `string` | `'The data could not be loaded'` | bf-chart-card's text when its data failed to load and it has no `error` slot. |
88
+ | `listItemUnread` | `string` | `'Unread'` | bf-list-item's visually hidden state text before the title of an `unread` row. |
87
89
  | `validation` | `BfValidationMessages` | required | Default error text per validator kind (see `BfValidationMessages`). |
88
90
 
89
91
  ## Uses
@@ -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,28 @@
1
+ # BfStepHeadingLevel
2
+
3
+ The heading level a step title can take, two, three or four
4
+
5
+ Type from `@bitforgehq/ui` · since 0.4.0
6
+
7
+ The heading level of a `bf-step` title, for a guide whose steps hold enough content (screenshots,
8
+ code) that a screen-reader user moves between them by heading.
9
+
10
+ ```ts
11
+ import { type BfStepHeadingLevel } from '@bitforgehq/ui';
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```ts
17
+ type BfStepHeadingLevel = 2 | 3 | 4
18
+ ```
19
+
20
+ ## Values
21
+
22
+ - `2`
23
+ - `3`
24
+ - `4`
25
+
26
+ ## Used by
27
+
28
+ - [bf-step](../components/step.md)
@@ -23,4 +23,4 @@ type BfTableAlign = 'start' | 'end'
23
23
 
24
24
  ## Used by
25
25
 
26
- - [BfTableColumn](bf-table-column.md)
26
+ - [BfTableColumnAlign](bf-table-column-align.md)
@@ -0,0 +1,33 @@
1
+ # BfTableColumnAlign
2
+
3
+ The inline alignment of a table column: start, end, or centred for controls
4
+
5
+ Type from `@bitforgehq/ui` · since 0.4.0
6
+
7
+ Where a `bf-table` column lines up its header and cells: a `BfTableAlign`, or `center` for a
8
+ column of controls such as the toggles of a settings matrix. A new type, so `Record`s over the
9
+ released `BfTableAlign` keep compiling.
10
+
11
+ ```ts
12
+ import { type BfTableColumnAlign } from '@bitforgehq/ui';
13
+ ```
14
+
15
+ ## Signature
16
+
17
+ ```ts
18
+ type BfTableColumnAlign = BfTableAlign | 'center'
19
+ ```
20
+
21
+ ## Values
22
+
23
+ - `start`
24
+ - `end`
25
+ - `center`
26
+
27
+ ## Uses
28
+
29
+ - [BfTableAlign](bf-table-align.md)
30
+
31
+ ## Used by
32
+
33
+ - [BfTableColumn](bf-table-column.md)
@@ -12,16 +12,16 @@ import { type BfTableColumn } from '@bitforgehq/ui';
12
12
 
13
13
  ## Properties
14
14
 
15
- | Name | Type | Default | Description |
16
- | ---------- | ----------------------------------- | --------- | ------------------------------------------------------------------------------------- |
17
- | `key` | `string` | required | The row property the default cell shows; also the key a `bfTableCell` template names. |
18
- | `label` | `string` | required | The header text. |
19
- | `sortable` | `boolean` | `false` | Whether the header is a button that sets the table's `sort`. |
20
- | `align` | `BfTableAlign` (`'start' \| 'end'`) | `'start'` | The inline alignment of the header and cells; `end` also sets tabular figures. |
15
+ | Name | Type | Default | Description |
16
+ | ---------- | ----------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
17
+ | `key` | `string` | required | The row property the default cell shows; also the key a `bfTableCell` template names. |
18
+ | `label` | `string` | required | The header text. |
19
+ | `sortable` | `boolean` | `false` | Whether the header is a button that sets the table's `sort`. |
20
+ | `align` | `BfTableColumnAlign` (`'start' \| 'end' \| 'center'`) | `'start'` | The inline alignment of the header and cells; `end` also sets tabular figures, `center` centres a cell's control (a toggle, a checkbox) in the column. |
21
21
 
22
22
  ## Uses
23
23
 
24
- - [BfTableAlign](bf-table-align.md)
24
+ - [BfTableColumnAlign](bf-table-column-align.md)
25
25
 
26
26
  ## Used by
27
27
 
@@ -41,6 +41,18 @@ The text of one cell.
41
41
  | `row` | `number` | The row's position, from 0. |
42
42
  | `column` | `string` | The column's header text. |
43
43
 
44
+ ### `getCellHarness<T extends ComponentHarness>(row: number, column: string, query: HarnessQuery<T>): Promise<T>`
45
+
46
+ A harness for a control in one cell, such as a `bf-toggle` of a settings matrix or a
47
+ `bf-select` in a custom cell. Throws for an unknown row or column, or when the cell holds no
48
+ matching control.
49
+
50
+ | Parameter | Type | Description |
51
+ | --------- | ----------------- | --------------------------------------------------- |
52
+ | `row` | `number` | The row's position, from 0. |
53
+ | `column` | `string` | The column's header text. |
54
+ | `query` | `HarnessQuery<T>` | The harness type, or a predicate from its `with()`. |
55
+
44
56
  ### `sortBy(column: string): Promise<void>`
45
57
 
46
58
  Clicks a sortable column's header, as a user would: ascending first, then descending.
@@ -54,6 +66,11 @@ Throws for an unknown or unsortable column.
54
66
 
55
67
  The sorted column (its `key`) and direction, from `aria-sort`.
56
68
 
69
+ ### `getSortSelect(): Promise<BfSelectHarness | null>`
70
+
71
+ The Sort by select in a stacked table's bar: its first option, Not sorted (`tableSortNone`),
72
+ sets `sort` to null and shows while it is; then each sortable column ascending and descending.
73
+
57
74
  ### `selectRow(index: number): Promise<void>`
58
75
 
59
76
  Checks one row's checkbox, as a user would; a selected row stays selected. Throws when the
@@ -74,4 +91,5 @@ The number of selected rows (checked row checkboxes).
74
91
 
75
92
  ## Uses
76
93
 
94
+ - [BfSelectHarness](bf-select-harness.md)
77
95
  - [BfTableSort](bf-table-sort.md)
@@ -0,0 +1,31 @@
1
+ # BfTimelineTone
2
+
3
+ The marker colour of a timeline event, neutral, primary or a status
4
+
5
+ Type from `@bitforgehq/ui` · since 0.4.0
6
+
7
+ The colour of a `bf-timeline-event`'s marker: `neutral` (the default), `primary`, or a status
8
+ (`success`, `warning`, `danger`, `info`), such as danger for a failed CI run.
9
+
10
+ ```ts
11
+ import { type BfTimelineTone } from '@bitforgehq/ui';
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```ts
17
+ type BfTimelineTone = 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | 'info'
18
+ ```
19
+
20
+ ## Values
21
+
22
+ - `neutral`
23
+ - `primary`
24
+ - `success`
25
+ - `warning`
26
+ - `danger`
27
+ - `info`
28
+
29
+ ## Used by
30
+
31
+ - [bf-timeline-event](../components/timeline-event.md)
@@ -0,0 +1,55 @@
1
+ # BfToggleHarness
2
+
3
+ Test harness for the toggle: reads its name and state and switches it
4
+
5
+ Class from `@bitforgehq/ui/testing` · since 0.4.0
6
+
7
+ Harness for `bf-toggle`. Its `label` filter matches the switch's name: the text of the elements
8
+ `ariaLabelledby` names, else `ariaLabel`, else the visible label, so a label-less switch in a
9
+ table cell or a list row is found the same way.
10
+
11
+ ```ts
12
+ import { BfToggleHarness } from '@bitforgehq/ui/testing';
13
+ ```
14
+
15
+ ## Signature
16
+
17
+ ```ts
18
+ class BfToggleHarness extends ComponentHarness
19
+ ```
20
+
21
+ ## Methods
22
+
23
+ ### `getLabel(): Promise<string>`
24
+
25
+ The switch's name, as the browser computes it: the text of the elements `ariaLabelledby`
26
+ names, else `ariaLabel`, else the visible label (the `label` text and the default slot).
27
+
28
+ ### `isChecked(): Promise<boolean>`
29
+
30
+ Whether the switch is on.
31
+
32
+ ### `isDisabled(): Promise<boolean>`
33
+
34
+ Whether the switch is disabled.
35
+
36
+ ### `isReadonly(): Promise<boolean>`
37
+
38
+ Whether the switch is read-only (`aria-readonly`): it shows its state but a click does nothing.
39
+
40
+ ### `toggle(): Promise<void>`
41
+
42
+ Clicks the switch, as a user would, so it turns on or off. Throws while it is disabled (a
43
+ user's click would do nothing); a read-only switch takes the click and stays as it is.
44
+
45
+ ### `check(): Promise<void>`
46
+
47
+ Turns the switch on with a click; an on switch stays on. Throws while it is disabled.
48
+
49
+ ### `uncheck(): Promise<void>`
50
+
51
+ Turns the switch off with a click; an off switch stays off. Throws while it is disabled.
52
+
53
+ ### `getErrorText(): Promise<string>`
54
+
55
+ The error text under the switch.