@bitforgehq/ui 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +598 -0
- package/README.md +18 -11
- package/ai/MANIFEST.index.json +306 -0
- package/ai/MANIFEST.json +8915 -3788
- package/ai/REFERENCE.index.json +476 -0
- package/ai/REFERENCE.json +5810 -2905
- package/ai/UI_GUIDE.md +212 -58
- package/ai/components/app-frame.md +328 -0
- 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 +119 -4
- 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/empty-state.md +99 -6
- package/ai/components/header.md +71 -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-toggle.md +287 -0
- package/ai/components/sidebar.md +541 -0
- package/ai/components/skeleton.md +215 -0
- package/ai/components/sparkline.md +188 -0
- package/ai/components/stat.md +297 -0
- package/ai/components/tab-group.md +226 -0
- package/ai/components/tab-panel.md +163 -0
- package/ai/components/table.md +697 -0
- package/ai/components/tabs.md +46 -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 +354 -0
- package/ai/components/tooltip.md +230 -0
- package/ai/components/top-nav.md +159 -0
- package/ai/reference/bf-app-frame-breakpoint.md +27 -0
- package/ai/reference/bf-app-frame-content-width.md +29 -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-empty-state-heading-level.md +1 -1
- package/ai/reference/bf-empty-state-heading.md +33 -0
- package/ai/reference/bf-labels.md +73 -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-sidebar-state-service.md +21 -0
- package/ai/reference/bf-sidebar-toggle-harness.md +32 -0
- package/ai/reference/bf-size.md +13 -0
- package/ai/reference/bf-skeleton-shape.md +28 -0
- package/ai/reference/bf-stat-appearance.md +33 -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-table-stack.md +29 -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_sidebar_state_storage.md +20 -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 +13 -4
- package/ai/reference/provide-bf-sidebar-state.md +20 -0
- package/ai/reference/slide-in-from-end.md +24 -0
- package/ai/reference/slide-out-to-end.md +24 -0
- package/bin/bf-ui.js +433 -3
- 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 +6566 -38
- package/fesm2022/bitforgehq-ui-overlay.mjs.map +1 -1
- package/fesm2022/bitforgehq-ui-testing.mjs +634 -1
- package/fesm2022/bitforgehq-ui-testing.mjs.map +1 -1
- package/fesm2022/bitforgehq-ui.mjs +5708 -137
- package/fesm2022/bitforgehq-ui.mjs.map +1 -1
- package/llms-full.txt +26766 -14470
- package/llms.txt +106 -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 +1895 -7
- package/types/bitforgehq-ui-testing.d.ts +782 -1
- package/types/bitforgehq-ui.d.ts +2393 -45
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,604 @@ All notable changes to `@bitforgehq/ui`. One `##` section per version; one `###`
|
|
|
4
4
|
|
|
5
5
|
The heading for the version being worked on carries `(unreleased)` in place of a date. At release time, that placeholder is replaced with the release date (`## 0.3.1 (unreleased)` becomes `## 0.3.1 (YYYY-MM-DD)`) in the same commit that bumps `projects/ui/package.json`. See "Releasing" in the root `README.md`. 0.3.0 is the first version published to npm; the 0.2.0 and 0.1.0 sections below are the history of versions that were never published.
|
|
6
6
|
|
|
7
|
+
## 0.3.2 (2026-10-29)
|
|
8
|
+
|
|
9
|
+
### docs site
|
|
10
|
+
|
|
11
|
+
The docs initial bundle (620 kB) warns at 640 kB instead of 600 kB: the example registry ships in
|
|
12
|
+
the initial bundle and gained this release's examples (moving it into a lazy chunk is the lasting
|
|
13
|
+
fix). The web demo loads its app frame lazily, like its pages, and its initial bundle (542 kB, the
|
|
14
|
+
stylesheet with every widget's classes) warns at 560 kB instead of 540 kB.
|
|
15
|
+
|
|
16
|
+
### tabs
|
|
17
|
+
|
|
18
|
+
The `## Desktop` docs point at `bf-app-frame` for the frame around the desktop navigation.
|
|
19
|
+
|
|
20
|
+
### header
|
|
21
|
+
|
|
22
|
+
The `## Desktop` docs say `bf-app-frame` supplies the app-level header bar below its breakpoint.
|
|
23
|
+
|
|
24
|
+
### app-frame
|
|
25
|
+
|
|
26
|
+
New `bf-app-frame` in `@bitforgehq/ui`: the frame of a desktop web app. Slots `sidebar` (a
|
|
27
|
+
`bf-sidebar`, in a column that sticks to the viewport at full height from the breakpoint up),
|
|
28
|
+
`brand`, `menu` (the narrow-screen `bf-menu-button`) and `actions` (the header bar shown below
|
|
29
|
+
the breakpoint) and the default slot (the page, in the `main` landmark). `breakpoint`
|
|
30
|
+
(`BfAppFrameBreakpoint`: `'md'` default, `'lg'`), `contentWidth` (`BfAppFrameContentWidth`:
|
|
31
|
+
`'md'` 48rem, `'lg'` 64rem, `'xl'` 80rem default, `'full'`) and `mainId`. A skip link, first in
|
|
32
|
+
the tab order and hidden until focused, moves focus to the main landmark by script, so it works
|
|
33
|
+
under `<base href="/">`; new label key `skipToContent` ("Skip to main content"). Inside another
|
|
34
|
+
`main` landmark the content drops its `main` role. Desktop only: the Capacitor shell keeps
|
|
35
|
+
`bf-tabs`.
|
|
36
|
+
|
|
37
|
+
### toolbar
|
|
38
|
+
|
|
39
|
+
On a narrow row the actions no longer end up alone on a row of their own: the status and the
|
|
40
|
+
actions are now one group that takes the rest of the last row and wraps as a whole, with the
|
|
41
|
+
status at the start and the actions at the inline end. The wide layout is unchanged, and a
|
|
42
|
+
toolbar without actions keeps the status as a plain item of the row. New `toolbar/narrow`
|
|
43
|
+
example at phone width.
|
|
44
|
+
|
|
45
|
+
### stat
|
|
46
|
+
|
|
47
|
+
New `variant="tile"`: a sunken, borderless tile (`surface-sunken`, the `card` radius and
|
|
48
|
+
padding) for a row of stats inside a raised `bf-card`; on it the icon tile turns `surface`.
|
|
49
|
+
`variant` now takes the new named type `BfStatAppearance` (`BfStatVariant | 'tile'`); the
|
|
50
|
+
released `BfStatVariant` keeps its two members, so `Record`s over it keep compiling. New
|
|
51
|
+
`stat/dashboard` example with one surface per level.
|
|
52
|
+
|
|
53
|
+
### card
|
|
54
|
+
|
|
55
|
+
New "Nesting surfaces" docs section: a raised card holds sunken tiles, never an outlined
|
|
56
|
+
surface (`flat`, a `card` stat), and each level of a dashboard keeps one surface style. New
|
|
57
|
+
`card/nesting` example. No code change.
|
|
58
|
+
|
|
59
|
+
### empty-state
|
|
60
|
+
|
|
61
|
+
`headingLevel` now takes the new named type `BfEmptyStateHeading` (`BfEmptyStateHeadingLevel |
|
|
62
|
+
1`): `1` renders the title as the page's `h1`, for an empty state that is the page (a not-found
|
|
63
|
+
or no-access page). The released `BfEmptyStateHeadingLevel` keeps its two members, so `Record`s
|
|
64
|
+
over it keep compiling. New "As the page" docs section with the `empty-state/page` example
|
|
65
|
+
(centred in a tall area, a primary action and a secondary link) and the code-only
|
|
66
|
+
`empty-state/not-found-page`.
|
|
67
|
+
|
|
68
|
+
### table
|
|
69
|
+
|
|
70
|
+
New opt-in `stack` input (`BfTableStack`: `'never'` by default, so existing tables do not
|
|
71
|
+
change, `'narrow'` or `'coarse'`): while the table is narrower than 36rem (a container query on
|
|
72
|
+
the host, which then gets `@container`) or, for `'coarse'`, under a coarse pointer at any width,
|
|
73
|
+
each body row renders as a sunken tile of label/value pairs. The markup stays a `table` with
|
|
74
|
+
explicit `table`, `rowgroup`, `row`, `columnheader` and `cell` roles (some browsers drop a
|
|
75
|
+
table's semantics once its display changes), the header row is visually hidden but still read,
|
|
76
|
+
the selection checkbox and the first cell head each tile, and every other cell shows its column
|
|
77
|
+
label (`data-label`, a `::before` with empty alternative text, so it is not read twice). A bar
|
|
78
|
+
above the tiles holds a labelled Select all checkbox and a Sort by `bf-select`, since the hidden
|
|
79
|
+
header's controls are not shown. New label keys `tableSortBy` ("Sort by"), `tableSortAscending`
|
|
80
|
+
and `tableSortDescending` (`"Hours, ascending"`). `BfTableHarness` reads and drives a stacked
|
|
81
|
+
table the same way. New `table/stacked` example and a Stacked rows docs section.
|
|
82
|
+
|
|
83
|
+
### sidebar-toggle
|
|
84
|
+
|
|
85
|
+
New `bf-sidebar-toggle` in `@bitforgehq/ui/overlay`: a text icon button placed inside a
|
|
86
|
+
`bf-sidebar` (header or footer) that flips the sidebar between full width and an icon rail by
|
|
87
|
+
writing its `collapsed` model, so `[(collapsed)]` sees every press. Its name and `bfTooltip` say
|
|
88
|
+
what the next press does (new label keys `sidebarCollapse` "Collapse sidebar" and `sidebarExpand`
|
|
89
|
+
"Expand sidebar"); `aria-expanded` follows the sidebar and `aria-controls` points at its `nav`.
|
|
90
|
+
Icons are the `collapse-icon` and `expand-icon` slots, only the matching one shown; `size` as
|
|
91
|
+
`bf-icon-button`. Outside a sidebar (in a `bf-top-nav`, or alone) it renders nothing. A
|
|
92
|
+
`BfSidebarToggleHarness` in `@bitforgehq/ui/testing` (`getLabel()`, `isExpanded()`, `toggle()`).
|
|
93
|
+
|
|
94
|
+
### sidebar
|
|
95
|
+
|
|
96
|
+
New `BfSidebarStateService` (a `collapsed` signal) and `provideBfSidebarState()` in
|
|
97
|
+
`@bitforgehq/ui`: bind the sidebar's `[(collapsed)]` to `sidebarState.collapsed` and the provider
|
|
98
|
+
stores every change under `bf-sidebar-collapsed` in `BF_SIDEBAR_STATE_STORAGE` (`localStorage` in
|
|
99
|
+
the browser, memory elsewhere), read back at the next start; without the provider nothing is
|
|
100
|
+
written, and on the server nothing is read. The sidebar's `nav` now has an id, for a toggle's
|
|
101
|
+
`aria-controls`. The docs gain "Remember the collapsed sidebar" and a "Footer" composition
|
|
102
|
+
(Settings link, theme menu, toggle, version line) that works expanded and as an icon rail.
|
|
103
|
+
|
|
104
|
+
### theme
|
|
105
|
+
|
|
106
|
+
Decision: the default primary stays indigo (`#2b26ba`). Making the Meadow Sage green the default
|
|
107
|
+
would recolour every app that relies on the indigo, a breaking change; a brand override recipe
|
|
108
|
+
gives a new app the green (or any brand) on day one instead. No token changes.
|
|
109
|
+
|
|
110
|
+
New `bf-ui theme <hex> [--dark <hex>]` command in the package's CLI (no new dependencies): it
|
|
111
|
+
derives the brand set (`--color-primary`, `-hover`, `-pressed`, `-soft`, `-soft-hover`,
|
|
112
|
+
`-soft-pressed`, `-strong`, `--color-on-primary`, `--color-primary-text`, `--color-selected`,
|
|
113
|
+
`--color-ring`) for light and dark mode with the docs configurator's OKLCH steps, keeping white
|
|
114
|
+
text on the brand in light mode; `--dark` sets the dark-mode primary (else the brand is lifted to
|
|
115
|
+
OKLCH lightness 0.76). It prints a `@theme` and a `.dark` block to paste after the theme import,
|
|
116
|
+
with every brand contrast pair's ratio in a comment (the pairs of the theme's contrast test, plus
|
|
117
|
+
`primary` at 3:1 on `bg` and `surface`), and exits 1 naming each pair below its minimum and the
|
|
118
|
+
nearest darker (light) or lighter (dark) shade that passes. The docs Theming page gains a "Brand
|
|
119
|
+
colour: the recipe" section (each token, how it is derived in light and dark, and why) with a
|
|
120
|
+
Meadow Sage green worked example (`bf-ui theme '#238652' --dark '#5cc48a'`; the design's
|
|
121
|
+
`#2f8f5b` gives white text only 4.04:1), and the agent guide and README point to the command.
|
|
122
|
+
|
|
123
|
+
## 0.3.1 (2026-10-29)
|
|
124
|
+
|
|
125
|
+
### calendar
|
|
126
|
+
|
|
127
|
+
New `bf-calendar` in `@bitforgehq/ui`: an inline month calendar for picking one date. The value
|
|
128
|
+
is a plain ISO date string (`'YYYY-MM-DD'`) or `null`, never a `Date`, so no time zone shifts
|
|
129
|
+
the day; `(changed)` emits a new pick and `(picked)` every pick (for a popover to close).
|
|
130
|
+
`[(month)]` (`'YYYY-MM'`) is the month on show. `min`, `max` and `disabledDate`
|
|
131
|
+
(`BfCalendarDisabledDate`) disable dates; `firstDayOfWeek` (`BfCalendarWeekday`) and `locale`
|
|
132
|
+
(default the document's `lang`) set the week and the `Intl` month and weekday names; `today`
|
|
133
|
+
overrides the device's date; `size` sets the cells (32/40/48 px, 44 px under a coarse pointer).
|
|
134
|
+
The header's title opens a month view and then a year view for quick jumps. An ARIA grid with
|
|
135
|
+
roving focus: arrows by day and week (mirrored in RTL), Page Up/Down by month (Shift by year),
|
|
136
|
+
Home/End to the week's ends, Enter/Space picks, Escape leaves the jump views; disabled days stay
|
|
137
|
+
focusable with `aria-disabled`. Signal Forms value contract like `bf-segmented`. New label keys
|
|
138
|
+
`calendarPreviousMonth`, `calendarNextMonth`, `calendarChooseMonth`, `calendarChooseYear`, and
|
|
139
|
+
a `BfCalendarHarness` in `@bitforgehq/ui/testing` (`getMonthLabel()`, `selectDate(iso)`,
|
|
140
|
+
`getSelected()`, `nextMonth()`, `previousMonth()`).
|
|
141
|
+
|
|
142
|
+
### toolbar
|
|
143
|
+
|
|
144
|
+
New `bf-toolbar` in `@bitforgehq/ui`: a wrapping `role="group"` row for the search field and
|
|
145
|
+
filters (default slot), a view switch (`bfSlot="view"`) and the trailing actions
|
|
146
|
+
(`bfSlot="actions"`, kept together at the inline end). `label` names the group; `status` renders
|
|
147
|
+
a polite `role="status"` live region for the result count. Its providers set
|
|
148
|
+
`provideBfDefaults({ size: 'sm' })`, so every projected control and field is `sm` unless it sets
|
|
149
|
+
`size` itself. Desktop only; in the Capacitor shell use `bf-header` actions and a `bf-sheet` of
|
|
150
|
+
filters.
|
|
151
|
+
|
|
152
|
+
### theme name
|
|
153
|
+
|
|
154
|
+
The README, the package description, `theme.css`, the agent guide and the docs site's Theming
|
|
155
|
+
page now say what the shipped colours are: the Meadow Sage palette with a neutral indigo default
|
|
156
|
+
primary (`#2b26ba`) that is meant to be overridden, so an indigo primary after install is
|
|
157
|
+
expected. The agent guide no longer calls the primary sage green. No token changes.
|
|
158
|
+
|
|
159
|
+
### tabs
|
|
160
|
+
|
|
161
|
+
The `## Desktop` docs name the desktop replacement: a `bf-top-nav` or `bf-sidebar` of
|
|
162
|
+
`a[bfNavItem]` links with `routerLinkActive` and `ariaCurrentWhenActive="page"`, driven by the
|
|
163
|
+
same destinations array as the shell's `bf-tab-bar`, with an example. No code change.
|
|
164
|
+
|
|
165
|
+
### back-button
|
|
166
|
+
|
|
167
|
+
The `## Desktop` docs and When to use name the desktop replacement, `bf-breadcrumb`, with an
|
|
168
|
+
example. No code change.
|
|
169
|
+
|
|
170
|
+
### header
|
|
171
|
+
|
|
172
|
+
The `## Desktop` docs and When to use name the desktop replacement, `bf-page-header` (with
|
|
173
|
+
`bf-breadcrumb` and `bf-toolbar`), with an example. No code change.
|
|
174
|
+
|
|
175
|
+
### color-scheme
|
|
176
|
+
|
|
177
|
+
New `provideBfColorScheme()` and `BfColorSchemeService` in `@bitforgehq/ui`, with no Capacitor:
|
|
178
|
+
the System / Light / Dark choice (`BfColorScheme`), toggling `dark` on `<html>`, following
|
|
179
|
+
`prefers-color-scheme` under `system` and storing the choice in `localStorage` under `bf-theme`
|
|
180
|
+
(`BF_COLOR_SCHEME_STORAGE`). Storage and the media query are read in the browser only, so a server
|
|
181
|
+
render starts light and writes nothing. A desktop web app no longer needs its own theme service.
|
|
182
|
+
|
|
183
|
+
### platform
|
|
184
|
+
|
|
185
|
+
`BfPlatformService` builds on `BfColorSchemeService`: `theme` and `dark` are its `scheme` and
|
|
186
|
+
`dark` signals, and the shell claims `<html>` through it, so the system bars still follow the
|
|
187
|
+
theme. Its public API, the `bf-theme` key and the in-memory fallback are unchanged;
|
|
188
|
+
`BF_THEME_STORAGE` is now the same token as `BF_COLOR_SCHEME_STORAGE`, so providing either one
|
|
189
|
+
moves the choice for both.
|
|
190
|
+
|
|
191
|
+
### badge
|
|
192
|
+
|
|
193
|
+
New `info` tone for informational labels such as a category, on the new `info` / `info-soft`
|
|
194
|
+
tokens (7.7:1 in light, 7.2:1 in dark; not derived from the primary). `variant` is now typed
|
|
195
|
+
`BfBadgeAppearance` (the five `BfBadgeVariant` tones plus `info`); `BfBadgeVariant` keeps its five
|
|
196
|
+
members, so code that maps over it keeps compiling.
|
|
197
|
+
|
|
198
|
+
### theme
|
|
199
|
+
|
|
200
|
+
New `--color-info` and `--color-info-soft` tokens in both modes (`text-info`, `bg-info-soft`),
|
|
201
|
+
used by the badge's `info` tone.
|
|
202
|
+
|
|
203
|
+
New `--animate-skeleton-shimmer` and `--animate-skeleton-shimmer-rtl` animations
|
|
204
|
+
(`animate-skeleton-shimmer`, 1.6 s, endless), the sweep of `bf-skeleton`'s shimmer from the
|
|
205
|
+
inline start.
|
|
206
|
+
New `--color-tooltip` and `--color-on-tooltip` tokens in both modes (`bg-tooltip`,
|
|
207
|
+
`text-on-tooltip`; 14.9:1 in light, 13.8:1 in dark), used by `bf-tooltip`.
|
|
208
|
+
New chart tokens in both modes for `@bitforgehq/ui/charts`: `--color-chart-1` … `--color-chart-8`
|
|
209
|
+
(a categorical palette in a fixed order: sage green, indigo, terracotta, teal, ochre, berry, violet,
|
|
210
|
+
olive; each ≥ 3:1 on `surface` and `bg`, adjacent slots distinct under colour vision deficiency),
|
|
211
|
+
`--color-chart-grid` (grid lines) and `--color-chart-axis` (the axis line, ≥ 3:1). New
|
|
212
|
+
`--animate-chart-draw`, `--animate-chart-grow-y`, `--animate-chart-grow-x` and
|
|
213
|
+
`--animate-chart-fade` animations, the charts' enter motion.
|
|
214
|
+
|
|
215
|
+
### icon
|
|
216
|
+
|
|
217
|
+
New `filled` input: fills the shape with `currentColor` and keeps the stroke, for a favourite
|
|
218
|
+
heart or a starred item. Only icons whose every shape is closed are filled (`Heart`, `Star`,
|
|
219
|
+
`Bookmark`, …); a stroke icon or an outline holding inner strokes renders as before, so `filled`
|
|
220
|
+
never paints the area a check mark encloses or hides a stroke. Put the state in the control's name
|
|
221
|
+
or `aria-pressed` too.
|
|
222
|
+
|
|
223
|
+
### list
|
|
224
|
+
|
|
225
|
+
New opt-in `divided` input: a `border` line between rows instead of a gap, with square rows whose
|
|
226
|
+
hover fill reaches the list's edges. On a card, `<bf-list [inset]="false" divided class="-mx-card">`
|
|
227
|
+
runs the rows edge to edge, and the rows take the card's inline padding so their text stays aligned
|
|
228
|
+
with the card's content. A divided inset list is one rounded `surface`. Lists without `divided`
|
|
229
|
+
look as before. When to use links `bf-table` for data compared across columns.
|
|
230
|
+
|
|
231
|
+
### icon-button
|
|
232
|
+
|
|
233
|
+
New `a[bfIconButton]` selector: put `bfIconButton` on your own `<a>` (with `href` or `routerLink`)
|
|
234
|
+
for an icon-only link such as back, open or edit. The `<a>` takes the variant, size, focus ring
|
|
235
|
+
and touch hit area, `label` becomes its `aria-label` (still required), and it behaves as a link
|
|
236
|
+
(Enter, Ctrl/Cmd-click and middle click open it; `clicked` emits on every click). `type` and
|
|
237
|
+
`disabled` do not apply, as on `a[bfButton]`. The `bf-icon-button` element is unchanged.
|
|
238
|
+
|
|
239
|
+
### button
|
|
240
|
+
|
|
241
|
+
New `ghost` variant: quiet and neutral (`text-muted` label, no fill at rest, `surface-muted` on
|
|
242
|
+
hover, `surface-pressed` on press), with the `text` variant's sizes, padding and disabled state,
|
|
243
|
+
for secondary toolbar actions and navigation rows. `a[bfButton]` with `aria-current="page"` shows
|
|
244
|
+
the current page: `ghost` and `text` links take the tonal fill, `outline` a primary border, so a
|
|
245
|
+
top nav built with `routerLinkActive` and `ariaCurrentWhenActive="page"` needs no `[variant]`
|
|
246
|
+
switch. `variant` is now typed `BfButtonAppearance` (the five `BfButtonVariant` styles plus
|
|
247
|
+
`ghost`); `BfButtonVariant` keeps its five members, so code that maps over it keeps compiling.
|
|
248
|
+
|
|
249
|
+
### card
|
|
250
|
+
|
|
251
|
+
The footer (`bfSlot="footer"`) sits on the card's bottom edge (`mt-auto`), so in a grid of cards
|
|
252
|
+
whose descriptions wrap differently every footer lines up. A card whose footer already followed
|
|
253
|
+
the body directly looks the same unless the card is taller than its content.
|
|
254
|
+
|
|
255
|
+
### packaging
|
|
256
|
+
|
|
257
|
+
The `bf-ui` bin entry points at `bin/bf-ui.js` without a leading `./`, the form npm stores, so
|
|
258
|
+
`npm publish` no longer warns that it cleaned the path. The command itself is unchanged.
|
|
259
|
+
|
|
260
|
+
### page-header
|
|
261
|
+
|
|
262
|
+
New `bf-page-header` in `@bitforgehq/ui`, the desktop page header: a `breadcrumb` slot above,
|
|
263
|
+
the `title` as an `h1` (`headingLevel` 2 for an `h2`, `BfPageHeaderHeadingLevel`) with an
|
|
264
|
+
optional `subtitle`, a `meta` slot for badges beside the title, a `title` slot for rich title
|
|
265
|
+
content, and an `actions` slot at the inline end that wraps under the title in a narrow window.
|
|
266
|
+
Empty slots take no space. It is a sibling of `bf-header` (`/mobile`), not a shell-aware mode of
|
|
267
|
+
it: no large title, no scroll-under surface, no safe areas.
|
|
268
|
+
|
|
269
|
+
### table
|
|
270
|
+
|
|
271
|
+
New `bf-table` and `ng-template[bfTableCell]` (`BfTableCellDirective`) in `@bitforgehq/ui`, a
|
|
272
|
+
data table for desktop pages: `rows`, `columns` (`BfTableColumn`: `key`, `label`, `sortable`,
|
|
273
|
+
`align` of `BfTableAlign`), `rowKey` (`BfTableRowKey`, the row's `id` by default) and a
|
|
274
|
+
visually hidden caption from `label`. Sortable headers set the `sort` model (`BfTableSort`,
|
|
275
|
+
`BfTableSortDirection`) and `aria-sort`; the consumer sorts the rows. `selectable` adds a
|
|
276
|
+
checkbox column bound to the `selection` model of row keys, with a mixed header checkbox named
|
|
277
|
+
by the new `tableSelectAll` label ("Select all rows") or `selectAllLabel`. A `bfTableCell`
|
|
278
|
+
template replaces one column's cells (`BfTableCellContext`; `bfTableCellOf` types the row), the
|
|
279
|
+
`empty` slot shows while there are no rows, `size` follows `controlSize`, and ArrowUp / ArrowDown
|
|
280
|
+
move focus between the controls of a column. New `BfTableHarness` in `@bitforgehq/ui/testing`.
|
|
281
|
+
|
|
282
|
+
The docs gain a Paging section and a `table/paged` example: one page of rows with a
|
|
283
|
+
`bf-pagination` under the table, back to page 1 on a sort.
|
|
284
|
+
|
|
285
|
+
### theme-switch
|
|
286
|
+
|
|
287
|
+
New `bf-theme-switch` in `@bitforgehq/ui`: System, Light and Dark as a three-option
|
|
288
|
+
`bf-segmented`, holding a `BfColorScheme` in `value` (`[(value)]`, `changed`), with `label`,
|
|
289
|
+
`size` and `fullWidth`. It injects no service; bind it to `BfColorSchemeService.scheme`
|
|
290
|
+
(`BfPlatformService.theme` in the shell). New `BfLabels` keys `theme`, `themeSystem`, `themeLight`
|
|
291
|
+
and `themeDark`.
|
|
292
|
+
|
|
293
|
+
### theme-menu-button
|
|
294
|
+
|
|
295
|
+
New `bf-theme-menu-button` in `@bitforgehq/ui/overlay`: a `bf-menu-button` whose menu holds
|
|
296
|
+
System, Light and Dark as radio items, for a crowded top bar. Same `value` / `changed` / `label`
|
|
297
|
+
as `bf-theme-switch`, plus `iconOnly`, `variant`, `size`, `placement` (default `'below-end'`) and
|
|
298
|
+
an `icon` slot for the consumer's sun or moon.
|
|
299
|
+
|
|
300
|
+
### description-list
|
|
301
|
+
|
|
302
|
+
New: `bf-description-list`, a native `dl` of label-value pairs for the details of one record, in
|
|
303
|
+
both shells. `layout="rows"` (default) divides the pairs with a `border` line and puts the label
|
|
304
|
+
beside the value once the list is 28rem wide (a container query, so a narrow pane stacks them);
|
|
305
|
+
`layout="grid"` lays them out as wrapping tiles. New type `BfDescriptionListLayout`.
|
|
306
|
+
|
|
307
|
+
### description-item
|
|
308
|
+
|
|
309
|
+
New: `div[bfDescriptionItem]`, one pair of a `bf-description-list`: its required `label` is the
|
|
310
|
+
`dt`, its content (text, a badge, a link) the `dd`.
|
|
311
|
+
|
|
312
|
+
### stat
|
|
313
|
+
|
|
314
|
+
New: `bf-stat`, one labelled figure in its own `dl`, with the value at the `title` size in
|
|
315
|
+
tabular figures, an `icon` slot for a tile at the start and a supporting line in the default slot.
|
|
316
|
+
`variant="card"` gives it the outlined `flat` card surface; `plain` (default) draws none. An
|
|
317
|
+
opt-in trend: `delta` (the formatted change, such as `+12%`; empty shows nothing) with `trend`
|
|
318
|
+
(`up`, `down`, `flat`) renders a pill beside the value with a CSS arrow mark and the direction as a
|
|
319
|
+
hidden word (new labels `statTrendUp`, `statTrendDown`, `statTrendFlat`). `trendIntent`
|
|
320
|
+
(`positive` default, up is good; `negative` when down is good, such as costs) picks `success` or
|
|
321
|
+
`danger`; flat is neutral. New types `BfStatVariant`, `BfStatTrend` and `BfStatTrendIntent`.
|
|
322
|
+
|
|
323
|
+
### breadcrumb
|
|
324
|
+
|
|
325
|
+
New `bf-breadcrumb` in `@bitforgehq/ui`, the desktop breadcrumb trail: a `nav` (named by
|
|
326
|
+
`label`, default `provideBfLabels()`'s new `breadcrumb` key, "Breadcrumb") around an `ol` of
|
|
327
|
+
`li[bfBreadcrumbItem]` levels, with CSS chevrons between them that are never announced.
|
|
328
|
+
`maxItems` collapses a longer trail to the first level and the last `maxItems - 1`, behind an
|
|
329
|
+
ellipsis button (the new `breadcrumbExpand` label, "Show 2 more levels") that shows the hidden
|
|
330
|
+
levels in place and focuses the first one; `bfSlot="overflow"` replaces that button with the app's
|
|
331
|
+
own control, such as a `bf-menu-button` of the hidden levels. It replaces the hand-built
|
|
332
|
+
breadcrumb the back-button docs showed.
|
|
333
|
+
|
|
334
|
+
### breadcrumb-item
|
|
335
|
+
|
|
336
|
+
New `li[bfBreadcrumbItem]` in `@bitforgehq/ui`: one level of a `bf-breadcrumb` on the app's own
|
|
337
|
+
`<li>`. A projected link takes the muted link look, the hover underline and the focus ring (at
|
|
338
|
+
least 24 px tall, 44 px under a coarse pointer); the last level is the current page, wrapped in
|
|
339
|
+
`aria-current="page"` with no chevron.
|
|
340
|
+
|
|
341
|
+
### sidebar
|
|
342
|
+
|
|
343
|
+
New `bf-sidebar`: the vertical navigation of a desktop app, a `nav` landmark with `header`,
|
|
344
|
+
default and `footer` slots, named by `label` (else the new `navigation` label, "Main").
|
|
345
|
+
`collapsed` (a model the app binds to its own toggle button) turns it into an icon rail. Below a
|
|
346
|
+
breakpoint, hide it with `hidden md:flex` and drive a `bf-menu-button` from the same routes.
|
|
347
|
+
|
|
348
|
+
### top-nav
|
|
349
|
+
|
|
350
|
+
New `bf-top-nav`: the horizontal navigation of a desktop app with few sections, a `nav` row of
|
|
351
|
+
`a[bfNavItem]` links that wraps in a narrow container, named by `label` (else `navigation`).
|
|
352
|
+
|
|
353
|
+
### nav-group
|
|
354
|
+
|
|
355
|
+
New `bf-nav-group`: a titled group of sidebar links, `role="group"` named by its small heading,
|
|
356
|
+
which stays the group's name (hidden visually) while the sidebar is collapsed.
|
|
357
|
+
|
|
358
|
+
### nav-item
|
|
359
|
+
|
|
360
|
+
New `a[bfNavItem]`: one destination of a `bf-sidebar` or `bf-top-nav` on the app's own
|
|
361
|
+
`<a routerLink routerLinkActive ariaCurrentWhenActive="page">`. Neutral at rest, the tonal fill
|
|
362
|
+
for the current page from `aria-current="page"` (as an `a[bfButton]` ghost link), an `icon` slot,
|
|
363
|
+
`size` from `controlSize` (44 px at least under a coarse pointer) and a `badge` count announced
|
|
364
|
+
with the new `navBadge(count)` label ("3 new"). In a collapsed sidebar it shows its icon only,
|
|
365
|
+
keeps its label as screen-reader text and as its `title`, and turns the badge into a dot.
|
|
366
|
+
|
|
367
|
+
### tab-group
|
|
368
|
+
|
|
369
|
+
New `bf-tab-group`: in-page tabs over the content they switch, in both shells. A `tablist` of
|
|
370
|
+
`button role="tab"` from its `bf-tab-panel` children, the `selected` model of the shown panel's
|
|
371
|
+
`value` with `changed` after a user change (unset or unknown shows the first enabled panel),
|
|
372
|
+
named by `label` (else the new `tabGroup` label, "Tabs"), `size` from `controlSize` (44 px at
|
|
373
|
+
least under a coarse pointer) and `fitted` to share the width. A roving tab stop and automatic
|
|
374
|
+
activation: the arrow keys (mirrored under `dir="rtl"`), Home and End select and focus a tab,
|
|
375
|
+
skipping disabled ones. The selected tab is underlined in `primary`; the row scrolls sideways
|
|
376
|
+
when the tabs do not fit. New `BfTabGroupHarness` in `@bitforgehq/ui/testing` (`getTabLabels()`,
|
|
377
|
+
`getSelectedLabel()`, `selectTab(label)`, `getPanelText()`).
|
|
378
|
+
|
|
379
|
+
### tab-panel
|
|
380
|
+
|
|
381
|
+
New `bf-tab-panel`: one tab of a `bf-tab-group` and its content (`role="tabpanel"`,
|
|
382
|
+
`aria-labelledby` its tab, `tabindex="0"`): `value`, `label`, `disabled`, a `badge` count
|
|
383
|
+
announced with `tabBadge(count)` and an `icon` slot shown in the tab. Content in an `ng-template`
|
|
384
|
+
is created only while the panel shows; `keepAlive` keeps it, hidden, once visited.
|
|
385
|
+
|
|
386
|
+
### docs site
|
|
387
|
+
|
|
388
|
+
The docs site's initial bundle is 587 kB and the embedded mobile demo's 653 kB, over their 580 kB
|
|
389
|
+
and 650 kB budget warnings: the example registry (one entry per example, in the initial bundle)
|
|
390
|
+
gained about 40 examples for the desktop widgets, and the mobile demo's project page and Me tab now
|
|
391
|
+
render `bf-stat`, `bf-description-list` and `bf-theme-switch`. The `initial` warnings
|
|
392
|
+
(`angular.json`) are now 600 kB (docs) and 670 kB (mobile demo). The web demo's initial bundle (511 kB:
|
|
393
|
+
its stylesheet holds the classes of every library widget, and the desktop frame now uses the side
|
|
394
|
+
panel and tooltips) warns at 540 kB instead of 500 kB. The mobile demo's (677 kB) warns at 690 kB: `BF_DEFAULT_LABELS`
|
|
395
|
+
is one object every app ships, and it gained about 60 keys for the new widgets.
|
|
396
|
+
|
|
397
|
+
### labels
|
|
398
|
+
|
|
399
|
+
New keys for the desktop widgets: `navigation` ("Main") and `navBadge(count)` ("{count} new")
|
|
400
|
+
for `bf-sidebar`, `bf-top-nav` and `a[bfNavItem]`; `breadcrumb` ("Breadcrumb") and
|
|
401
|
+
`breadcrumbExpand(count)` ("Show 2 more levels") for `bf-breadcrumb`; `tableSelectAll` ("Select
|
|
402
|
+
all rows") for `bf-table`; `theme`, `themeSystem`, `themeLight` and `themeDark` for
|
|
403
|
+
`bf-theme-switch` and `bf-theme-menu-button`.
|
|
404
|
+
|
|
405
|
+
New keys for `bf-pagination`: `pagination` ("Pagination"), `previousPage` ("Previous page"),
|
|
406
|
+
`nextPage` ("Next page"), `pageOf(page, count)` ("Page 3 of 12") and `goToPage(page)` ("Page 3").
|
|
407
|
+
|
|
408
|
+
New keys for the `bf-stat` trend: `statTrendUp` ("Up"), `statTrendDown` ("Down") and
|
|
409
|
+
`statTrendFlat` ("No change"), the hidden direction word before a delta.
|
|
410
|
+
New keys for `@bitforgehq/ui/charts`: `chart` ("Chart"), `chartLegend` ("Legend"), `chartValues`
|
|
411
|
+
("Data points, arrow keys move between them"), `chartShowData` ("Show data"), `chartHideData`
|
|
412
|
+
("Hide data"), `chartCategory` ("Category"), `chartValue` ("Value"), `chartEmpty` ("No data to
|
|
413
|
+
show") and `chartError` ("The data could not be loaded").
|
|
414
|
+
|
|
415
|
+
### skeleton
|
|
416
|
+
|
|
417
|
+
New `bf-skeleton` in `@bitforgehq/ui`, a loading placeholder for both shells: `shape` (the new
|
|
418
|
+
`BfSkeletonShape`: `text` lines, a `rect` or a `circle`), `lines` for several text lines with a
|
|
419
|
+
shorter last one, and `width` / `height` as CSS lengths. It draws the `surface-sunken` fill with a
|
|
420
|
+
`surface` shimmer that sweeps from the inline start (hidden under reduced motion) and carries
|
|
421
|
+
`aria-hidden="true"`; the docs mark the loading region with `aria-busy="true"` and show a card and
|
|
422
|
+
a table of skeleton rows.
|
|
423
|
+
|
|
424
|
+
### pagination
|
|
425
|
+
|
|
426
|
+
New `bf-pagination` in `@bitforgehq/ui`, page navigation for both shells: a `nav` (named by
|
|
427
|
+
`label`, else the new `pagination` label) with Previous and Next buttons around the page buttons.
|
|
428
|
+
`[(page)]` is 1-based; the count comes from `pageCount`, else `total` over `pageSize` (default 10).
|
|
429
|
+
The row keeps the first and the last page and `siblings` (default 1) on each side of the current
|
|
430
|
+
one, which carries `aria-current="page"`, and turns hidden runs into an `aria-hidden` ellipsis, at
|
|
431
|
+
a constant number of slots. `compact` shows "Page 3 of 12" (`pageOf`) between the arrows as a
|
|
432
|
+
polite live region. At the ends the arrows are `aria-disabled` and stay focusable. `size` follows
|
|
433
|
+
`controlSize`; the chevrons are CSS and mirror under `dir="rtl"`. New `BfPaginationHarness` in
|
|
434
|
+
`@bitforgehq/ui/testing` (`getCurrentPage()`, `getPageCount()`, `getVisiblePages()`, `goTo()`,
|
|
435
|
+
`next()`, `previous()`).
|
|
436
|
+
|
|
437
|
+
### side-panel
|
|
438
|
+
|
|
439
|
+
New `BfSidePanelService` and `bf-side-panel` in `@bitforgehq/ui/overlay`: a full-height panel
|
|
440
|
+
that slides in from the inline end edge (the left under `dir="rtl"`; a cross-fade under reduced
|
|
441
|
+
motion). `open(component | template, { data, width, modal, ariaLabel, injector })` returns a
|
|
442
|
+
`BfSidePanelRef<R, C>` (`close(result)`, `afterClosed`, `closed()`, `componentInstance`); the
|
|
443
|
+
content injects it and `BF_SIDE_PANEL_DATA`, and a template gets `{ $implicit: ref, data }`
|
|
444
|
+
(`BfSidePanelTemplateContext`). `width` is a `BfSidePanelWidth`: `sm` 360 px, `md` 480 px
|
|
445
|
+
(default), `lg` 640 px, capped at the viewport. Modal by default (a scrim that closes it, a focus
|
|
446
|
+
trap, an inert page, no page scroll); `modal: false` keeps the page usable beside it, and
|
|
447
|
+
`Escape` closes it only while focus is inside it. `bf-side-panel` renders the `title` as the
|
|
448
|
+
`h2` the panel is labelled by, a close button named by the `close` label (`closeLabel`), a
|
|
449
|
+
scrolling body and a `footer` slot kept at the bottom. New `BfSidePanelHarness` in
|
|
450
|
+
`@bitforgehq/ui/testing` (`getTitle()`, `close()`, `isOpen()`). Desktop only; in the Capacitor
|
|
451
|
+
shell use `bf-sheet` or `bf-modal`.
|
|
452
|
+
|
|
453
|
+
### overlay core
|
|
454
|
+
|
|
455
|
+
New `modal` option of `BfOverlayService.open()` (default true): `modal: false` opens an overlay
|
|
456
|
+
with no backdrop, no focus trap and no `aria-modal`, outside `BfOverlayStack` (the page stays
|
|
457
|
+
usable and scrollable); focus moves in, `Escape` closes it only while focus is inside it, and on
|
|
458
|
+
close focus returns to the opener only from inside it. New `position: 'end'` (full height
|
|
459
|
+
against the inline end edge) through the new `BfOverlayPlacement` type
|
|
460
|
+
(`BfOverlayPosition | 'end'`), the type of `BfOverlayOptions.position` now. New motion helpers
|
|
461
|
+
`slideInFromEnd()` and `slideOutToEnd()`, mirrored under `dir="rtl"`.
|
|
462
|
+
|
|
463
|
+
### tooltip
|
|
464
|
+
|
|
465
|
+
New `[bfTooltip]` (`BfTooltipDirective`) and its `bf-tooltip` pill (`BfTooltipComponent`) in
|
|
466
|
+
`@bitforgehq/ui/overlay`: a short hint beside a control after a 500 ms hover or at once on keyboard
|
|
467
|
+
focus, hidden on leave, blur and `Escape`, and kept while the pointer moves onto it (WCAG 1.4.13).
|
|
468
|
+
`bfTooltipPlacement` (`BfTooltipPlacement`: `top` default, `bottom`, `start`, `end`, logical)
|
|
469
|
+
flips when it would overflow. While it shows, the control is described by it
|
|
470
|
+
(`aria-describedby`). Nothing shows under a coarse pointer. Fades in over 120 ms, not under
|
|
471
|
+
reduced motion. New `BfTooltipHarness` in `@bitforgehq/ui/testing`.
|
|
472
|
+
|
|
473
|
+
### popover
|
|
474
|
+
|
|
475
|
+
New `[bfPopoverTriggerFor]` (`BfPopoverTriggerDirective`, exported as `bfPopoverTrigger`) and the
|
|
476
|
+
`bf-popover` panel (`BfPopoverComponent`) in `@bitforgehq/ui/overlay`: a non-modal `role="dialog"`
|
|
477
|
+
panel anchored to its trigger, for filters, details or a small form. `bfPopoverPlacement`
|
|
478
|
+
(`BfPopoverPlacement`, the menu's four placements), `bfPopoverLabel`, `(bfPopoverOpened)` and
|
|
479
|
+
`(bfPopoverClosed)`, and `open()`, `close()`, `toggle()`, `isOpen()`. The trigger's control gets
|
|
480
|
+
`aria-haspopup="dialog"`, `aria-expanded` and `aria-controls`; focus moves in on open, `Tab` is not
|
|
481
|
+
trapped (it closes the panel past either end), and `Escape`, a click outside or a navigation close
|
|
482
|
+
it and return focus. New `BfPopoverHarness` in `@bitforgehq/ui/testing`.
|
|
483
|
+
|
|
484
|
+
### menu
|
|
485
|
+
|
|
486
|
+
The menu's positions now come from the anchored-panel positioning the popover and tooltip share.
|
|
487
|
+
No behaviour change.
|
|
488
|
+
|
|
489
|
+
### combobox
|
|
490
|
+
|
|
491
|
+
New `bf-combobox` (`BfComboboxComponent<T>`) in `@bitforgehq/ui/overlay`: a text field with a
|
|
492
|
+
list of options that filters as you type, to pick one value (the ARIA 1.2 combobox pattern with a
|
|
493
|
+
list autocomplete). `[(value)]` is `T | null`; `options` are `BfComboboxOption<T>` (`value`,
|
|
494
|
+
`label`, `description`, `disabled`, `group`); `compareWith`, `label`, `ariaLabel`,
|
|
495
|
+
`ariaLabelledby`, `placeholder`, `helpText`, `errorMessage`, `size` (`fieldSize`) and the Signal
|
|
496
|
+
Forms value contract like `bf-select`. Filters by label, ignoring case and accents; `filter`
|
|
497
|
+
(`BfComboboxFilter<T>`) replaces the match, `null` turns local filtering off for server results,
|
|
498
|
+
`(queried)` emits the typed text and `loading` shows a spinner row. Arrow keys open and move
|
|
499
|
+
(wrapping), `Home`/`End`, `Enter` picks, `Escape` closes then drops the typed text, `Tab` picks
|
|
500
|
+
nothing; leaving the field reverts unmatched text to the picked label (emptied text clears the
|
|
501
|
+
value, `(changed)` emits `null`). Grouped options render in named `role="group"` sections. New
|
|
502
|
+
label key `comboboxEmpty` ("No results", or `emptyLabel`) and a `BfComboboxHarness` in
|
|
503
|
+
`@bitforgehq/ui/testing` (`open()`, `type(query)`, `getOptionLabels()`, `selectOption(label)`,
|
|
504
|
+
`getValueText()`, `getChipLabels()`, `removeChip(label)`) for both comboboxes.
|
|
505
|
+
|
|
506
|
+
### multi-combobox
|
|
507
|
+
|
|
508
|
+
New `bf-multi-combobox` (`BfMultiComboboxComponent<T>`) in `@bitforgehq/ui/overlay`: the
|
|
509
|
+
combobox for several values, `[(value)]` a `readonly T[]`. Picked values are tags inside the
|
|
510
|
+
field, each with a remove button named by the new `comboboxRemove(label)` label ("Remove
|
|
511
|
+
Design"); `Backspace` in the empty field removes the last tag, the list stays open after a pick
|
|
512
|
+
and picked options carry a check mark (`aria-multiselectable`, `aria-selected`). Same options,
|
|
513
|
+
filtering, server search and Signal Forms contract as `bf-combobox`.
|
|
514
|
+
|
|
515
|
+
### date-input
|
|
516
|
+
|
|
517
|
+
New `bf-date-input` in `@bitforgehq/ui/overlay`: a date field typed part by part, the day, month
|
|
518
|
+
and year as spinbuttons in the locale's order and separators (`Intl.DateTimeFormat`
|
|
519
|
+
`formatToParts`), with muted placeholders (dd/mm/yyyy). Digits type in and move on by themselves,
|
|
520
|
+
Arrow Up/Down step with wrapping, Backspace clears, Arrow Left/Right move between the parts. The
|
|
521
|
+
value is an ISO date string (`'YYYY-MM-DD'`), `null` while empty or incomplete, and `(changed)`
|
|
522
|
+
emits each user change. `picker` (`BfDateInputPicker`: `'calendar'`, the default, or `'none'`)
|
|
523
|
+
adds a button that opens a `bf-calendar` in an anchored popover; a pick closes it and returns
|
|
524
|
+
focus. `min`, `max` and `disabledDate` bound the calendar and show the field's own error for a
|
|
525
|
+
typed date outside them (as for an incomplete or impossible one). `native` renders
|
|
526
|
+
`input type="date"` under a coarse pointer, for the Capacitor shell. `locale`, `size`
|
|
527
|
+
(`fieldSize`), `openPicker()`, `closePicker()`, `focus()`, and the Signal Forms value contract
|
|
528
|
+
like `bf-input`. New label keys `dateInputDay`, `dateInputMonth`, `dateInputYear`,
|
|
529
|
+
`dateInputOpenCalendar`, `dateInputInvalid` and `dateInputUnavailable`, and a
|
|
530
|
+
`BfDateInputHarness` in `@bitforgehq/ui/testing` (`getValue()`, `setValue(text)`, `clear()`,
|
|
531
|
+
`openPicker()`, `pickDate(iso)`).
|
|
532
|
+
|
|
533
|
+
### time-input
|
|
534
|
+
|
|
535
|
+
New `bf-time-input` in `@bitforgehq/ui/overlay`: a time-of-day field typed as hour and minute
|
|
536
|
+
(and second with `seconds`), with an AM/PM part under a 12-hour clock. The clock follows the
|
|
537
|
+
locale; `hourCycle` (`BfTimeInputHourCycle`: `'h12'` or `'h23'`) forces one. The value is an ISO
|
|
538
|
+
time on a 24-hour clock (`'HH:mm'`, `'HH:mm:ss'` with seconds). `picker` (`BfTimeInputPicker`:
|
|
539
|
+
`'list'`, the default, or `'none'`) adds a button that opens a listbox of times every `step`
|
|
540
|
+
minutes (30 by default), scrolled to the value; `min` and `max` disable the times outside them
|
|
541
|
+
and show an error for a typed one. `native` renders `input type="time"` under a coarse pointer.
|
|
542
|
+
New label keys `timeInputHour`, `timeInputMinute`, `timeInputSecond`, `timeInputDayPeriod`,
|
|
543
|
+
`timeInputOpenList`, `timeInputInvalid`, `timeInputMin` and `timeInputMax`, and a
|
|
544
|
+
`BfTimeInputHarness` in `@bitforgehq/ui/testing` (`setValue(text)`, `pickTime(time)`).
|
|
545
|
+
|
|
546
|
+
### datetime-input
|
|
547
|
+
|
|
548
|
+
New `bf-datetime-input` in `@bitforgehq/ui/overlay`: the date and the time parts in one field,
|
|
549
|
+
valued as a local ISO date and time without a zone (`'YYYY-MM-DDTHH:mm'`). `picker`
|
|
550
|
+
(`BfDateTimeInputPicker`: `'popover'`, the default, or `'none'`) opens one popover with the
|
|
551
|
+
calendar and a list of times side by side: a day moves focus to the list, a time closes it.
|
|
552
|
+
`min` and `max` bound the calendar and, on their own day, the list. `step`, `hourCycle`,
|
|
553
|
+
`disabledDate`, `native` (`input type="datetime-local"`) and the field contract as on the date
|
|
554
|
+
and time inputs. New `BfDateTimeInputHarness` in `@bitforgehq/ui/testing` (`pickDate(iso)`,
|
|
555
|
+
`pickTime(time)`, `setValue(text)`).
|
|
556
|
+
|
|
557
|
+
### line-chart
|
|
558
|
+
|
|
559
|
+
New `bf-line-chart` in the new `@bitforgehq/ui/charts` entry (which imports only Angular core and
|
|
560
|
+
common and the root entry): one or more `series` (`BfChartSeries`: `name`, `values` with `null`
|
|
561
|
+
for a gap) over `categories`, drawn in SVG with the `--color-chart-*` tokens. A value axis of nice
|
|
562
|
+
ticks (1, 2 or 5 × 10ⁿ), a legend that shows and hides series (`aria-pressed`; `legend`:
|
|
563
|
+
`BfChartLegendPosition` `top`, `bottom` or `none`), a crosshair tooltip with markers on hover and
|
|
564
|
+
on keyboard focus (the plot is focusable; the arrow keys, `Home`, `End` and `Escape` move between
|
|
565
|
+
the categories and a polite live region reads each one), and a Show data toggle that shows the data
|
|
566
|
+
as a table. `area` fills under the lines, `curve` (`BfChartCurve`: `linear` or `smooth`, a monotone
|
|
567
|
+
cubic) shapes them, `valueFormat` formats every value (default `Intl.NumberFormat` in the document's
|
|
568
|
+
language), `height` sets the plot's height and the width follows the container (`ResizeObserver`;
|
|
569
|
+
600 px on the server). Lines draw in on the first render and on every data change, not under
|
|
570
|
+
reduced motion; `dir="rtl"` mirrors the category axis.
|
|
571
|
+
New `BfChartHarness` in `@bitforgehq/ui/testing` for the line, bar and donut charts:
|
|
572
|
+
`getLabel()`, `getSeriesNames()`, `isSeriesShown()`, `toggleSeries()` and `showData()` (the data
|
|
573
|
+
table's rows).
|
|
574
|
+
|
|
575
|
+
### bar-chart
|
|
576
|
+
|
|
577
|
+
New `bf-bar-chart` in `@bitforgehq/ui/charts`: series over categories as bars from a zero
|
|
578
|
+
baseline, side by side or `stacked`, vertical or `orientation="horizontal"`
|
|
579
|
+
(`BfBarChartOrientation`), with the line chart's value axis, legend, tooltip, keyboard reading and
|
|
580
|
+
data table. Bars grow from the baseline on the first render and on every data change, not under
|
|
581
|
+
reduced motion; `dir="rtl"` mirrors the horizontal axis.
|
|
582
|
+
|
|
583
|
+
### donut-chart
|
|
584
|
+
|
|
585
|
+
New `bf-donut-chart` in `@bitforgehq/ui/charts`: `slices` (`BfDonutSlice`: `label`, `value`) as
|
|
586
|
+
the parts of a whole, with a `thickness`, a `center` slot for a total, a legend that hides slices
|
|
587
|
+
(the shares follow), a tooltip with each slice's value and share, keyboard reading and a data
|
|
588
|
+
table. Slices draw in along the ring, not under reduced motion, and run counter-clockwise under
|
|
589
|
+
`dir="rtl"`.
|
|
590
|
+
|
|
591
|
+
### sparkline
|
|
592
|
+
|
|
593
|
+
New `bf-sparkline` in `@bitforgehq/ui/charts`: a tiny line of one series with no axes, legend or
|
|
594
|
+
tooltip, for a `bf-stat`'s supporting line or a table cell; `area`, `curve` and `height`, a dot on
|
|
595
|
+
the latest value. With a `label` it is a named image, without one it is decorative.
|
|
596
|
+
|
|
597
|
+
### chart-card
|
|
598
|
+
|
|
599
|
+
New `bf-chart-card` in `@bitforgehq/ui/charts`: the `flat` card surface around one chart, with a
|
|
600
|
+
`title` (the chart's name when it has no `label`; `headingLevel`, `BfChartCardHeadingLevel` 2 or
|
|
601
|
+
3), a `period` slot for the range control, the `legend` placement for the chart inside, and
|
|
602
|
+
`loading` (a `bf-skeleton`, `aria-busy`), `empty` and `error` states with slots of the same names
|
|
603
|
+
and the `chartEmpty` and `chartError` labels as fallbacks.
|
|
604
|
+
|
|
7
605
|
## 0.3.0 (2026-09-28)
|
|
8
606
|
|
|
9
607
|
### Migration
|