@bitforgehq/ui 0.3.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 (281) hide show
  1. package/CHANGELOG.md +3665 -0
  2. package/LICENSE +21 -0
  3. package/README.md +175 -0
  4. package/ai/MANIFEST.index.json +383 -0
  5. package/ai/MANIFEST.json +7528 -0
  6. package/ai/REFERENCE.index.json +1461 -0
  7. package/ai/REFERENCE.json +7213 -0
  8. package/ai/UI_GUIDE.md +1159 -0
  9. package/ai/components/action-bar.md +209 -0
  10. package/ai/components/action-sheet.md +526 -0
  11. package/ai/components/alert-dialog.md +509 -0
  12. package/ai/components/alert.md +376 -0
  13. package/ai/components/avatar.md +146 -0
  14. package/ai/components/back-button.md +286 -0
  15. package/ai/components/badge.md +171 -0
  16. package/ai/components/button.md +431 -0
  17. package/ai/components/card.md +303 -0
  18. package/ai/components/checkbox.md +418 -0
  19. package/ai/components/chip-group.md +205 -0
  20. package/ai/components/chip.md +300 -0
  21. package/ai/components/content.md +474 -0
  22. package/ai/components/desktop-toast.md +420 -0
  23. package/ai/components/dialog.md +962 -0
  24. package/ai/components/empty-state.md +146 -0
  25. package/ai/components/field.md +319 -0
  26. package/ai/components/header.md +809 -0
  27. package/ai/components/icon-button.md +221 -0
  28. package/ai/components/icon.md +176 -0
  29. package/ai/components/input.md +455 -0
  30. package/ai/components/list-item.md +326 -0
  31. package/ai/components/list.md +178 -0
  32. package/ai/components/menu-button.md +377 -0
  33. package/ai/components/menu.md +661 -0
  34. package/ai/components/modal.md +613 -0
  35. package/ai/components/number-input.md +423 -0
  36. package/ai/components/page.md +299 -0
  37. package/ai/components/progress.md +215 -0
  38. package/ai/components/radio-group.md +432 -0
  39. package/ai/components/refresher.md +377 -0
  40. package/ai/components/segmented.md +517 -0
  41. package/ai/components/select.md +510 -0
  42. package/ai/components/sheet.md +845 -0
  43. package/ai/components/spinner.md +171 -0
  44. package/ai/components/stack-outlet.md +661 -0
  45. package/ai/components/tab-bar.md +427 -0
  46. package/ai/components/tab.md +295 -0
  47. package/ai/components/tabs.md +408 -0
  48. package/ai/components/textarea.md +371 -0
  49. package/ai/components/toast.md +522 -0
  50. package/ai/components/toggle.md +387 -0
  51. package/ai/reference/bf-action-directive.md +21 -0
  52. package/ai/reference/bf-action-sheet-action-role.md +27 -0
  53. package/ai/reference/bf-action-sheet-action.md +28 -0
  54. package/ai/reference/bf-action-sheet-options.md +28 -0
  55. package/ai/reference/bf-action-sheet-service.md +33 -0
  56. package/ai/reference/bf-alert-dialog-button-role.md +27 -0
  57. package/ai/reference/bf-alert-dialog-button.md +27 -0
  58. package/ai/reference/bf-alert-dialog-options.md +29 -0
  59. package/ai/reference/bf-alert-dialog-service.md +34 -0
  60. package/ai/reference/bf-alert-variant.md +28 -0
  61. package/ai/reference/bf-autocapitalize.md +30 -0
  62. package/ai/reference/bf-avatar-size.md +27 -0
  63. package/ai/reference/bf-avatar-variant.md +28 -0
  64. package/ai/reference/bf-back-at-root.md +28 -0
  65. package/ai/reference/bf-back-button-service.md +40 -0
  66. package/ai/reference/bf-badge-variant.md +29 -0
  67. package/ai/reference/bf-button-size.md +29 -0
  68. package/ai/reference/bf-button-type.md +28 -0
  69. package/ai/reference/bf-button-variant.md +29 -0
  70. package/ai/reference/bf-card-padding.md +26 -0
  71. package/ai/reference/bf-card-variant.md +28 -0
  72. package/ai/reference/bf-chip-group-mode.md +27 -0
  73. package/ai/reference/bf-chip-variant.md +26 -0
  74. package/ai/reference/bf-compare-with.md +24 -0
  75. package/ai/reference/bf-component-overlay-ref.md +33 -0
  76. package/ai/reference/bf-confirm-button-role.md +26 -0
  77. package/ai/reference/bf-confirm-button.md +27 -0
  78. package/ai/reference/bf-confirm-options.md +31 -0
  79. package/ai/reference/bf-confirm-size.md +26 -0
  80. package/ai/reference/bf-content-scroll-event.md +21 -0
  81. package/ai/reference/bf-defaults-options.md +32 -0
  82. package/ai/reference/bf-defaults.md +28 -0
  83. package/ai/reference/bf-desktop-toast-config.md +28 -0
  84. package/ai/reference/bf-desktop-toast-harness.md +33 -0
  85. package/ai/reference/bf-desktop-toast-options.md +28 -0
  86. package/ai/reference/bf-desktop-toast-position.md +28 -0
  87. package/ai/reference/bf-desktop-toast-service.md +42 -0
  88. package/ai/reference/bf-dialog-config.md +44 -0
  89. package/ai/reference/bf-dialog-harness.md +52 -0
  90. package/ai/reference/bf-dialog-ref.md +44 -0
  91. package/ai/reference/bf-dialog-role.md +26 -0
  92. package/ai/reference/bf-dialog-service.md +55 -0
  93. package/ai/reference/bf-dialog-size.md +31 -0
  94. package/ai/reference/bf-dialog-template-context.md +32 -0
  95. package/ai/reference/bf-empty-state-heading-level.md +26 -0
  96. package/ai/reference/bf-enter-key-hint.md +31 -0
  97. package/ai/reference/bf-field-control-class.md +32 -0
  98. package/ai/reference/bf-field-control-state.md +28 -0
  99. package/ai/reference/bf-field-size.md +29 -0
  100. package/ai/reference/bf-haptics-impact-style.md +27 -0
  101. package/ai/reference/bf-haptics-notification-type.md +27 -0
  102. package/ai/reference/bf-haptics-service.md +41 -0
  103. package/ai/reference/bf-harness-filters.md +29 -0
  104. package/ai/reference/bf-horizontal-scroll-directive.md +129 -0
  105. package/ai/reference/bf-icon-button-variant.md +28 -0
  106. package/ai/reference/bf-icon-size.md +27 -0
  107. package/ai/reference/bf-input-autocapitalize.md +36 -0
  108. package/ai/reference/bf-input-enter-key-hint.md +38 -0
  109. package/ai/reference/bf-input-input-mode.md +38 -0
  110. package/ai/reference/bf-input-mode.md +32 -0
  111. package/ai/reference/bf-input-type.md +35 -0
  112. package/ai/reference/bf-jsdom-shim-options.md +22 -0
  113. package/ai/reference/bf-keyboard-assist-behavior.md +26 -0
  114. package/ai/reference/bf-keyboard-assist-directive.md +185 -0
  115. package/ai/reference/bf-keyboard-phase.md +30 -0
  116. package/ai/reference/bf-keyboard-service.md +50 -0
  117. package/ai/reference/bf-labels-overrides.md +26 -0
  118. package/ai/reference/bf-labels.md +44 -0
  119. package/ai/reference/bf-menu-button-harness.md +40 -0
  120. package/ai/reference/bf-menu-button-variant.md +27 -0
  121. package/ai/reference/bf-menu-divider-directive.md +13 -0
  122. package/ai/reference/bf-menu-group-directive.md +14 -0
  123. package/ai/reference/bf-menu-harness.md +55 -0
  124. package/ai/reference/bf-menu-item-checkbox-directive.md +31 -0
  125. package/ai/reference/bf-menu-item-directive.md +31 -0
  126. package/ai/reference/bf-menu-item-harness.md +52 -0
  127. package/ai/reference/bf-menu-item-radio-directive.md +29 -0
  128. package/ai/reference/bf-menu-placement.md +29 -0
  129. package/ai/reference/bf-menu-trigger-directive.md +46 -0
  130. package/ai/reference/bf-modal-options.md +30 -0
  131. package/ai/reference/bf-modal-presentation.md +26 -0
  132. package/ai/reference/bf-modal-service.md +38 -0
  133. package/ai/reference/bf-nav-controller.md +59 -0
  134. package/ai/reference/bf-nav-direction.md +23 -0
  135. package/ai/reference/bf-nav-target.md +21 -0
  136. package/ai/reference/bf-number-input-mode.md +28 -0
  137. package/ai/reference/bf-number-input-step.md +25 -0
  138. package/ai/reference/bf-overlay-auto-focus.md +29 -0
  139. package/ai/reference/bf-overlay-controller.md +22 -0
  140. package/ai/reference/bf-overlay-host.md +36 -0
  141. package/ai/reference/bf-overlay-options.md +53 -0
  142. package/ai/reference/bf-overlay-position.md +30 -0
  143. package/ai/reference/bf-overlay-ref.md +53 -0
  144. package/ai/reference/bf-overlay-role.md +27 -0
  145. package/ai/reference/bf-overlay-service.md +53 -0
  146. package/ai/reference/bf-overlay-stack-options.md +24 -0
  147. package/ai/reference/bf-overlay-stack.md +81 -0
  148. package/ai/reference/bf-overlay-template-context.md +24 -0
  149. package/ai/reference/bf-overscroll-stretch-directive.md +163 -0
  150. package/ai/reference/bf-page-context.md +24 -0
  151. package/ai/reference/bf-platform-service.md +53 -0
  152. package/ai/reference/bf-platform.md +28 -0
  153. package/ai/reference/bf-progress-size.md +26 -0
  154. package/ai/reference/bf-progress-tone.md +28 -0
  155. package/ai/reference/bf-radio-group-harness.md +49 -0
  156. package/ai/reference/bf-radio-group-orientation.md +26 -0
  157. package/ai/reference/bf-radio-option.md +30 -0
  158. package/ai/reference/bf-refresher-refresh-event.md +22 -0
  159. package/ai/reference/bf-segment-option.md +29 -0
  160. package/ai/reference/bf-segmented-harness.md +48 -0
  161. package/ai/reference/bf-segmented-size.md +29 -0
  162. package/ai/reference/bf-select-harness.md +70 -0
  163. package/ai/reference/bf-select-option.md +29 -0
  164. package/ai/reference/bf-sheet-auto-focus.md +29 -0
  165. package/ai/reference/bf-sheet-options.md +32 -0
  166. package/ai/reference/bf-sheet-ref.md +45 -0
  167. package/ai/reference/bf-sheet-service.md +34 -0
  168. package/ai/reference/bf-shell-config-mode.md +28 -0
  169. package/ai/reference/bf-shell-config.md +38 -0
  170. package/ai/reference/bf-shell-dynamic-type-limit.md +21 -0
  171. package/ai/reference/bf-shell-dynamic-type.md +25 -0
  172. package/ai/reference/bf-shell-mode.md +28 -0
  173. package/ai/reference/bf-shell-testing-options.md +26 -0
  174. package/ai/reference/bf-size.md +45 -0
  175. package/ai/reference/bf-spinner-size.md +27 -0
  176. package/ai/reference/bf-stack-change.md +22 -0
  177. package/ai/reference/bf-stack-reuse-strategy.md +32 -0
  178. package/ai/reference/bf-stack-transition-event.md +26 -0
  179. package/ai/reference/bf-stack-transition.md +26 -0
  180. package/ai/reference/bf-stacked-overlay.md +23 -0
  181. package/ai/reference/bf-system-bars-style.md +38 -0
  182. package/ai/reference/bf-tab-bar-controller.md +51 -0
  183. package/ai/reference/bf-tab-bar-host.md +52 -0
  184. package/ai/reference/bf-tab-context.md +32 -0
  185. package/ai/reference/bf-tab-links.md +37 -0
  186. package/ai/reference/bf-testing-options.md +27 -0
  187. package/ai/reference/bf-text-scale-service.md +35 -0
  188. package/ai/reference/bf-theme.md +27 -0
  189. package/ai/reference/bf-toast-action.md +25 -0
  190. package/ai/reference/bf-toast-controller.md +17 -0
  191. package/ai/reference/bf-toast-dismiss-reason.md +29 -0
  192. package/ai/reference/bf-toast-options.md +29 -0
  193. package/ai/reference/bf-toast-position.md +26 -0
  194. package/ai/reference/bf-toast-ref.md +41 -0
  195. package/ai/reference/bf-toast-service.md +39 -0
  196. package/ai/reference/bf-toggle-label-position.md +26 -0
  197. package/ai/reference/bf-transition-kind.md +28 -0
  198. package/ai/reference/bf-validation-message.md +31 -0
  199. package/ai/reference/bf-validation-messages.md +33 -0
  200. package/ai/reference/bf-view-event.md +28 -0
  201. package/ai/reference/bf-view-lifecycle.md +41 -0
  202. package/ai/reference/bf-view-state.md +28 -0
  203. package/ai/reference/bf_default_labels.md +21 -0
  204. package/ai/reference/bf_default_values.md +21 -0
  205. package/ai/reference/bf_defaults.md +21 -0
  206. package/ai/reference/bf_desktop_toast_defaults.md +21 -0
  207. package/ai/reference/bf_dialog_data.md +17 -0
  208. package/ai/reference/bf_labels.md +21 -0
  209. package/ai/reference/bf_overlay_data.md +19 -0
  210. package/ai/reference/bf_overlay_host.md +21 -0
  211. package/ai/reference/bf_sheet_default_snap_points.md +17 -0
  212. package/ai/reference/bf_shell_config.md +21 -0
  213. package/ai/reference/bf_shell_defaults.md +21 -0
  214. package/ai/reference/bf_tab_bar.md +21 -0
  215. package/ai/reference/bf_tab_bar_controller.md +21 -0
  216. package/ai/reference/bf_tab_context.md +21 -0
  217. package/ai/reference/bf_tab_links.md +21 -0
  218. package/ai/reference/bf_theme_storage.md +19 -0
  219. package/ai/reference/create-transition.md +36 -0
  220. package/ai/reference/duration_fast.md +17 -0
  221. package/ai/reference/duration_md.md +17 -0
  222. package/ai/reference/duration_overlay.md +17 -0
  223. package/ai/reference/duration_push.md +17 -0
  224. package/ai/reference/fade-down.md +26 -0
  225. package/ai/reference/fade-in.md +25 -0
  226. package/ai/reference/fade-out.md +25 -0
  227. package/ai/reference/fade-up.md +26 -0
  228. package/ai/reference/inject-shell-mode.md +23 -0
  229. package/ai/reference/install-bf-jsdom-shims.md +31 -0
  230. package/ai/reference/ios_duration.md +17 -0
  231. package/ai/reference/ios_easing.md +17 -0
  232. package/ai/reference/is-text-entry.md +25 -0
  233. package/ai/reference/max_complete_ms.md +17 -0
  234. package/ai/reference/md-transition.md +31 -0
  235. package/ai/reference/md_duration.md +17 -0
  236. package/ai/reference/md_easing.md +17 -0
  237. package/ai/reference/overlay_duration.md +21 -0
  238. package/ai/reference/overlay_easing.md +19 -0
  239. package/ai/reference/overlay_reduced_duration.md +17 -0
  240. package/ai/reference/pop-frames-at.md +25 -0
  241. package/ai/reference/prefers-reduced-motion.md +25 -0
  242. package/ai/reference/provide-bf-defaults.md +33 -0
  243. package/ai/reference/provide-bf-desktop-toast.md +28 -0
  244. package/ai/reference/provide-bf-labels.md +38 -0
  245. package/ai/reference/provide-bf-shell-testing.md +34 -0
  246. package/ai/reference/provide-bf-shell.md +41 -0
  247. package/ai/reference/provide-bf-testing.md +33 -0
  248. package/ai/reference/reduced-transition.md +28 -0
  249. package/ai/reference/reduced_duration.md +17 -0
  250. package/ai/reference/resolve-shell-mode.md +33 -0
  251. package/ai/reference/scale-in.md +25 -0
  252. package/ai/reference/settle-duration.md +25 -0
  253. package/ai/reference/settle-pop.md +33 -0
  254. package/ai/reference/settle_easing.md +17 -0
  255. package/ai/reference/should-complete-pop.md +26 -0
  256. package/ai/reference/slide-down.md +26 -0
  257. package/ai/reference/slide-up.md +26 -0
  258. package/ai/reference/with-bf-shell-routing.md +19 -0
  259. package/bin/bf-ui.js +81 -0
  260. package/fesm2022/bitforgehq-ui-icons.mjs +230 -0
  261. package/fesm2022/bitforgehq-ui-icons.mjs.map +1 -0
  262. package/fesm2022/bitforgehq-ui-mobile.mjs +5530 -0
  263. package/fesm2022/bitforgehq-ui-mobile.mjs.map +1 -0
  264. package/fesm2022/bitforgehq-ui-number-input.mjs +680 -0
  265. package/fesm2022/bitforgehq-ui-number-input.mjs.map +1 -0
  266. package/fesm2022/bitforgehq-ui-overlay.mjs +2675 -0
  267. package/fesm2022/bitforgehq-ui-overlay.mjs.map +1 -0
  268. package/fesm2022/bitforgehq-ui-testing.mjs +402 -0
  269. package/fesm2022/bitforgehq-ui-testing.mjs.map +1 -0
  270. package/fesm2022/bitforgehq-ui.mjs +7765 -0
  271. package/fesm2022/bitforgehq-ui.mjs.map +1 -0
  272. package/llms-full.txt +25394 -0
  273. package/llms.txt +329 -0
  274. package/package.json +94 -0
  275. package/theme.css +253 -0
  276. package/types/bitforgehq-ui-icons.d.ts +50 -0
  277. package/types/bitforgehq-ui-mobile.d.ts +2914 -0
  278. package/types/bitforgehq-ui-number-input.d.ts +282 -0
  279. package/types/bitforgehq-ui-overlay.d.ts +1514 -0
  280. package/types/bitforgehq-ui-testing.d.ts +495 -0
  281. package/types/bitforgehq-ui.d.ts +3499 -0
@@ -0,0 +1,3499 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ElementRef, EnvironmentProviders, InjectionToken, Provider, Signal } from "@angular/core";
3
+ import { FormCheckboxControl, FormValueControl, ValidationError } from "@angular/forms/signals";
4
+ /**
5
+ * The one control-height scale: sm 32 px, md 40 px, lg 48 px.
6
+ *
7
+ * @summary The three height steps every sized field and control shares
8
+ * @since 0.3.0
9
+ */
10
+ type BfSize = 'sm' | 'md' | 'lg';
11
+ /**
12
+ * App-wide widget defaults, read by every sized widget whose `size` input is left unset.
13
+ *
14
+ * @summary The default height steps of text fields and of actions and choice controls
15
+ * @since 0.3.0
16
+ */
17
+ interface BfDefaults {
18
+ /**
19
+ * Height step of text fields: bf-input, bf-number-input, bf-select, bf-textarea.
20
+ * @default 'md'
21
+ */
22
+ readonly fieldSize: BfSize;
23
+ /**
24
+ * Height step of actions and choice controls: bf-button, bf-icon-button, bf-chip, bf-segmented,
25
+ * bf-checkbox, bf-toggle, bf-radio-group.
26
+ * @default 'md'
27
+ */
28
+ readonly controlSize: BfSize;
29
+ }
30
+ /**
31
+ * Options of `provideBfDefaults()`: any step left out keeps the parent injector's value.
32
+ *
33
+ * @summary The size steps provideBfDefaults sets, each one falling back to the parent
34
+ * @since 0.3.0
35
+ */
36
+ interface BfDefaultsOptions extends Partial<BfDefaults> {
37
+ /** Sets `fieldSize` and `controlSize` together; an explicit `fieldSize`/`controlSize` wins. */
38
+ readonly size?: BfSize;
39
+ }
40
+ /**
41
+ * Library defaults: compact `md` everywhere (desktop first).
42
+ *
43
+ * @summary The library's built-in widget defaults, the compact md step everywhere
44
+ * @since 0.3.0
45
+ */
46
+ export declare const BF_DEFAULT_VALUES: BfDefaults;
47
+ /**
48
+ * The widget defaults in effect for the current injector; set them with `provideBfDefaults()`.
49
+ *
50
+ * @summary Injection token holding the widget defaults in effect for an injector
51
+ * @since 0.3.0
52
+ */
53
+ export declare const BF_DEFAULTS: InjectionToken<BfDefaults>;
54
+ /**
55
+ * App-wide (ApplicationConfig) or sub-tree (a component's `providers`) widget defaults, merged
56
+ * over the nearest parent's. Capacitor apps: `provideBfDefaults({ fieldSize: 'lg' })` keeps the
57
+ * 0.2 phone look; `{ size: 'lg' }` enlarges every control.
58
+ *
59
+ * @param options The steps to set; any step left out keeps the parent's.
60
+ * @returns The provider of `BF_DEFAULTS`.
61
+ * @summary Sets the default field and control sizes for an app or a sub-tree
62
+ * @since 0.3.0
63
+ */
64
+ export declare function provideBfDefaults(options: BfDefaultsOptions): Provider;
65
+ /**
66
+ * Default text per validator kind, part of `BfLabels`; override with `provideBfLabels()`.
67
+ *
68
+ * @summary The default error text of each validator kind, shown under a form field
69
+ * @since 0.3.0
70
+ */
71
+ interface BfValidationMessages {
72
+ /**
73
+ * `required` (Signal Forms and Reactive Forms; `Validators.requiredTrue` reports `required` too).
74
+ * @default 'Fill in this field'
75
+ */
76
+ readonly required: string;
77
+ /**
78
+ * `email`.
79
+ * @default 'Enter a valid email address'
80
+ */
81
+ readonly email: string;
82
+ /**
83
+ * `pattern`.
84
+ * @default 'Use the expected format'
85
+ */
86
+ readonly pattern: string;
87
+ /**
88
+ * `parse`: the text could not be read as a value (e.g. a number field).
89
+ * @default 'Enter a valid number'
90
+ */
91
+ readonly parse: string;
92
+ /**
93
+ * `min`, given the lower limit.
94
+ * @default (min) => `Enter ${min} or more`
95
+ */
96
+ readonly min: (min: number) => string;
97
+ /**
98
+ * `max`, given the upper limit.
99
+ * @default (max) => `Enter ${max} or less`
100
+ */
101
+ readonly max: (max: number) => string;
102
+ /**
103
+ * `minLength` (Signal Forms) and `minlength` (Reactive Forms), given the required length.
104
+ * @default (length) => `Use at least ${length} characters`
105
+ */
106
+ readonly minLength: (length: number) => string;
107
+ /**
108
+ * `maxLength` (Signal Forms) and `maxlength` (Reactive Forms), given the allowed length.
109
+ * @default (length) => `Use at most ${length} characters`
110
+ */
111
+ readonly maxLength: (length: number) => string;
112
+ /**
113
+ * `minDate`, given the earliest date.
114
+ * @default (date) => `Pick ${date.toLocaleDateString()} or later`
115
+ */
116
+ readonly minDate: (date: Date) => string;
117
+ /**
118
+ * `maxDate`, given the latest date.
119
+ * @default (date) => `Pick ${date.toLocaleDateString()} or earlier`
120
+ */
121
+ readonly maxDate: (date: Date) => string;
122
+ /**
123
+ * Any other kind without its own message.
124
+ * @default 'Check this value'
125
+ */
126
+ readonly fallback: string;
127
+ }
128
+ /**
129
+ * The text for one error: its own `message`, else the default for its `kind` (Signal Forms kinds
130
+ * `required|email|pattern|parse|min|max|minLength|maxLength|minDate|maxDate`, and the Reactive
131
+ * interop kinds `required|email|pattern|min|max|minlength|maxlength` whose limits sit
132
+ * in `context`), else `fallback`. Reads limits through type guards, never `any`.
133
+ *
134
+ * @param error A Signal Forms error, or a Reactive Forms error adapted to one.
135
+ * @param messages The default texts, usually `inject(BF_LABELS).validation`.
136
+ * @returns The text to show under the field.
137
+ * @summary Turns one validation error into the text a form field shows under it
138
+ * @since 0.3.0
139
+ */
140
+ export declare function bfValidationMessage(error: ValidationError, messages: BfValidationMessages): string;
141
+ /**
142
+ * Every built-in user-facing string of the library; replace any of them with `provideBfLabels()`.
143
+ *
144
+ * @summary Every built-in user-facing string of the library, one key per string
145
+ * @since 0.3.0
146
+ */
147
+ interface BfLabels {
148
+ /**
149
+ * bf-spinner's accessible name (a loading bf-button's spinner is decorative and has none).
150
+ * @default 'Loading'
151
+ */
152
+ readonly loading: string;
153
+ /**
154
+ * bf-alert's dismiss button.
155
+ * @default 'Dismiss'
156
+ */
157
+ readonly dismiss: string;
158
+ /**
159
+ * bf-tab-bar's navigation name.
160
+ * @default 'Main'
161
+ */
162
+ readonly tabBar: string;
163
+ /**
164
+ * bf-tab's announcement of a numeric badge.
165
+ * @default (count) => `${count} new`
166
+ */
167
+ readonly tabBadge: (count: number) => string;
168
+ /**
169
+ * bf-back-button's label.
170
+ * @default 'Back'
171
+ */
172
+ readonly back: string;
173
+ /**
174
+ * BfAlertDialogService's default button.
175
+ * @default 'OK'
176
+ */
177
+ readonly ok: string;
178
+ /**
179
+ * BfActionSheetService's cancel row.
180
+ * @default 'Cancel'
181
+ */
182
+ readonly cancel: string;
183
+ /**
184
+ * An action sheet's name when it has no title.
185
+ * @default 'Actions'
186
+ */
187
+ readonly actions: string;
188
+ /**
189
+ * bf-sheet's name without an ariaLabel or heading.
190
+ * @default 'Sheet'
191
+ */
192
+ readonly sheet: string;
193
+ /**
194
+ * bf-modal's name without an ariaLabel or heading.
195
+ * @default 'Modal'
196
+ */
197
+ readonly modal: string;
198
+ /**
199
+ * bf-refresher's status while refreshing.
200
+ * @default 'Refreshing'
201
+ */
202
+ readonly refreshing: string;
203
+ /**
204
+ * bf-dialog's close button, and bf-sheet's screen-reader Close.
205
+ * @default 'Close'
206
+ */
207
+ readonly close: string;
208
+ /**
209
+ * bf-sheet's grabber button below the top snap point: the next press expands the sheet.
210
+ * @default 'Expand'
211
+ */
212
+ readonly expand: string;
213
+ /**
214
+ * bf-sheet's grabber button at the top snap point: the next press collapses the sheet.
215
+ * @default 'Collapse'
216
+ */
217
+ readonly collapse: string;
218
+ /**
219
+ * bf-sheet's snap position (1-based), announced politely when it changes and part of the
220
+ * grabber button's name.
221
+ * @default (position, count) => `Sheet at ${position} of ${count}`
222
+ */
223
+ readonly sheetPosition: (position: number, count: number) => string;
224
+ /**
225
+ * A dialog's name without an ariaLabel, a bf-dialog title or a heading.
226
+ * @default 'Dialog'
227
+ */
228
+ readonly dialog: string;
229
+ /**
230
+ * The desktop toast stack's region name.
231
+ * @default 'Notifications'
232
+ */
233
+ readonly notifications: string;
234
+ /** Default error text per validator kind (see `BfValidationMessages`). */
235
+ readonly validation: BfValidationMessages;
236
+ }
237
+ /**
238
+ * Options of `provideBfLabels()`: any key left out keeps the parent injector's string.
239
+ *
240
+ * @summary The strings provideBfLabels replaces, each one falling back to the parent
241
+ * @since 0.3.0
242
+ */
243
+ type BfLabelsOverrides = Partial<Omit<BfLabels, 'validation'>> & {
244
+ readonly validation?: Partial<BfValidationMessages>;
245
+ };
246
+ /**
247
+ * The library's built-in English strings.
248
+ *
249
+ * @summary The library's built-in English strings, the labels every widget starts from
250
+ * @since 0.3.0
251
+ */
252
+ export declare const BF_DEFAULT_LABELS: BfLabels;
253
+ /**
254
+ * The strings in effect for the current injector; set them with `provideBfLabels()`.
255
+ *
256
+ * @summary Injection token holding the user-facing strings in effect for an injector
257
+ * @since 0.3.0
258
+ */
259
+ export declare const BF_LABELS: InjectionToken<BfLabels>;
260
+ /**
261
+ * Replaces built-in strings, merged over the parent's (validation merged key by key); a key left
262
+ * out or set to `undefined` keeps the parent's string. In `ApplicationConfig.providers` it covers
263
+ * every string. In a component's `providers` it covers that sub-tree's widgets and form controls
264
+ * (`loading`, `dismiss`, `tabBar`, `tabBadge`, `back`, `refreshing`, `validation`); the overlay
265
+ * services (`ok`, `cancel`, `actions`, `sheet`, `modal`, `close`, `expand`, `collapse`,
266
+ * `sheetPosition`, `dialog`, `notifications`) are
267
+ * root singletons and pick it up only when the caller passes its injector:
268
+ * `open(…, { injector: inject(Injector) })`.
269
+ *
270
+ * @param overrides The strings to replace; any key left out keeps the parent's.
271
+ * @returns The provider of `BF_LABELS`.
272
+ * @summary Replaces built-in strings for an app or a sub-tree, such as a translation
273
+ * @since 0.3.0
274
+ */
275
+ export declare function provideBfLabels(overrides: BfLabelsOverrides): Provider;
276
+ /**
277
+ * The diameter of a `bf-spinner`: sm, md or lg.
278
+ *
279
+ * @summary The three spinner diameters, from inline text to a page loading state
280
+ * @since 0.1.0
281
+ */
282
+ type BfSpinnerSize = 'sm' | 'md' | 'lg';
283
+ /**
284
+ * Indeterminate progress indicator. Inherits `currentColor`, so place it inside a colored parent
285
+ * (a button, a muted paragraph) rather than coloring it directly.
286
+ *
287
+ * @example
288
+ * <p class="flex items-center gap-2 text-text-muted"><bf-spinner size="sm" /> Loading recipes</p>
289
+ * @summary Indeterminate loading spinner in three sizes that inherits its parent's text color
290
+ * @category Feedback
291
+ * @since 0.1.0
292
+ */
293
+ export declare class BfSpinnerComponent {
294
+ /** Visual size: 16, 20 or 24 px (the `bf-icon` sizes). */
295
+ readonly size: import("@angular/core").InputSignal<BfSpinnerSize>;
296
+ /** Screen-reader text; keep it a short verb phrase. Empty falls back to `provideBfLabels()`'s
297
+ * `loading` ("Loading"). Not rendered while `decorative`. */
298
+ readonly label: import("@angular/core").InputSignal<string>;
299
+ /** Hides the spinner from assistive tech (no status role, no live region, no label), for a
300
+ * spinner inside a control that already reports its busy state, such as a loading `bf-button`. */
301
+ readonly decorative: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
302
+ private readonly labels;
303
+ /** The spinner's box in px (16, 20 or 24) for its `size`.
304
+ * @deprecated 0.3.0 use the size input; removed in 0.4.0 */
305
+ readonly px: import("@angular/core").Signal<number>;
306
+ /** @internal The ring's classes: the shared ring plus the size's box and border width. */
307
+ readonly ringClasses: import("@angular/core").Signal<string>;
308
+ /** The rendered screen-reader text: `label`, else the `loading` label. */
309
+ readonly name: import("@angular/core").Signal<string>;
310
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfSpinnerComponent, never>;
311
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfSpinnerComponent, "bf-spinner", never, {
312
+ "size": {
313
+ "alias": "size";
314
+ "required": false;
315
+ "isSignal": true;
316
+ };
317
+ "label": {
318
+ "alias": "label";
319
+ "required": false;
320
+ "isSignal": true;
321
+ };
322
+ "decorative": {
323
+ "alias": "decorative";
324
+ "required": false;
325
+ "isSignal": true;
326
+ };
327
+ }, {}, never, never, true, never>;
328
+ }
329
+ /**
330
+ * The visual style of a `bf-button`: primary (filled), tonal (soft tint), outline, text or danger.
331
+ *
332
+ * @summary The five visual styles of a button, from filled primary to plain text
333
+ * @since 0.1.0
334
+ */
335
+ type BfButtonVariant = 'primary' | 'tonal' | 'outline' | 'text' | 'danger';
336
+ /**
337
+ * The height step of a `bf-button`; the same scale as every sized widget.
338
+ *
339
+ * @deprecated 0.3.0 use BfSize; removed in 1.0.0
340
+ * @summary Former name of the shared size scale for buttons, kept until 1.0.0
341
+ * @since 0.1.0
342
+ */
343
+ type BfButtonSize = BfSize;
344
+ /**
345
+ * The native `type` of a `bf-button`: button, submit or reset.
346
+ *
347
+ * @summary The native button types, for a plain action, a form submit or reset
348
+ * @since 0.1.0
349
+ */
350
+ type BfButtonType = 'button' | 'submit' | 'reset';
351
+ /** The class maps of bf-button, shared with `bf-menu-button` (`@bitforgehq/ui/overlay`) through
352
+ * the internal `ɵBF_BUTTON_CLASSES` export so the two never drift. */
353
+ declare const BUTTON_CLASSES: {
354
+ readonly base: string;
355
+ readonly variant: Record<BfButtonVariant, string>;
356
+ readonly pressed: Record<BfButtonVariant, string>;
357
+ readonly size: Record<BfSize, string>;
358
+ readonly padding: Record<BfSize, string>;
359
+ readonly textPadding: Record<BfSize, string>;
360
+ };
361
+ /**
362
+ * Pill-shaped action button with five variants, three sizes, a loading state and icon slots. Put
363
+ * the label in the default slot and icons in the `icon-start` / `icon-end` slots; never place a
364
+ * `bf-button` inside another interactive element. For navigation, put `bfButton` on your own `<a>`
365
+ * (with `href` or `routerLink`): it renders as a real link that looks like the button.
366
+ *
367
+ * @example
368
+ * <bf-button (clicked)="save()">Save changes</bf-button>
369
+ * <bf-button variant="tonal" size="sm" [loading]="saving()">
370
+ * <bf-icon bfSlot="icon-start" [icon]="Plus" />
371
+ * New task
372
+ * </bf-button>
373
+ * <a bfButton variant="outline" routerLink="/projects">All projects</a>
374
+ * @summary Pill-shaped action button with five variants, three sizes and a loading state
375
+ * @category Actions
376
+ * @since 0.1.0
377
+ * @slot icon-start An icon before the label.
378
+ * @slot default The label.
379
+ * @slot icon-end An icon after the label.
380
+ */
381
+ export declare class BfButtonComponent {
382
+ /** Visual style: primary (filled), tonal (soft tint), outline, text, danger. */
383
+ readonly variant: import("@angular/core").InputSignal<BfButtonVariant>;
384
+ /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`controlSize`,
385
+ * `md` by default). */
386
+ readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
387
+ /** Native button type. Use `submit` inside a form. Ignored on `a[bfButton]`. */
388
+ readonly type: import("@angular/core").InputSignal<BfButtonType>;
389
+ /** Disables the control and swallows clicks. Ignored on `a[bfButton]`: a link is never
390
+ * disabled; render a disabled `bf-button` instead. */
391
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
392
+ /** Shows a spinner instead of the start icon and blocks activation. The button stays focusable
393
+ * (`aria-disabled` and `aria-busy`, never native `disabled`) and keeps its variant fill. Ignored
394
+ * on `a[bfButton]`. */
395
+ readonly loading: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
396
+ /** Stretches the button to its container's width. */
397
+ readonly fullWidth: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
398
+ /** Emitted on click while enabled and not loading; on `a[bfButton]`, on every click (the link
399
+ * still navigates). */
400
+ readonly clicked: import("@angular/core").OutputEmitterRef<Event>;
401
+ private readonly defaults;
402
+ /** Whether the host is the consumer's `<a>` (`a[bfButton]`) rather than a `bf-button` element. */
403
+ protected readonly isLink: boolean;
404
+ /** The size in effect: `size`, else the app's `controlSize` default. */
405
+ protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
406
+ readonly classes: import("@angular/core").Signal<string>;
407
+ /** The host's classes: the whole button on a link, else the wrapper's display and width. A link
408
+ * adds `no-underline!`: important, so an unlayered global rule of the app
409
+ * (`a { text-decoration: underline }`) cannot underline it, as it would beat a layered utility. */
410
+ readonly hostClasses: import("@angular/core").Signal<string>;
411
+ /**
412
+ * A click on `a[bfButton]` emits `clicked`; the browser (or `routerLink`) still follows it.
413
+ * @internal
414
+ */
415
+ onHostClick(event: Event): void;
416
+ /**
417
+ * The inner button's click: emits `clicked` unless disabled or loading.
418
+ * @internal
419
+ */
420
+ onClick(event: Event): void;
421
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfButtonComponent, never>;
422
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfButtonComponent, "bf-button, a[bfButton]", never, {
423
+ "variant": {
424
+ "alias": "variant";
425
+ "required": false;
426
+ "isSignal": true;
427
+ };
428
+ "size": {
429
+ "alias": "size";
430
+ "required": false;
431
+ "isSignal": true;
432
+ };
433
+ "type": {
434
+ "alias": "type";
435
+ "required": false;
436
+ "isSignal": true;
437
+ };
438
+ "disabled": {
439
+ "alias": "disabled";
440
+ "required": false;
441
+ "isSignal": true;
442
+ };
443
+ "loading": {
444
+ "alias": "loading";
445
+ "required": false;
446
+ "isSignal": true;
447
+ };
448
+ "fullWidth": {
449
+ "alias": "fullWidth";
450
+ "required": false;
451
+ "isSignal": true;
452
+ };
453
+ }, {
454
+ "clicked": "clicked";
455
+ }, never, ["[bfSlot=icon-start]", "*", "[bfSlot=icon-end]"], true, never>;
456
+ }
457
+ /**
458
+ * The visual style of a `bf-icon-button`: tonal, primary, outline or text.
459
+ *
460
+ * @summary The four visual styles of an icon button, from tonal to plain text
461
+ * @since 0.1.0
462
+ */
463
+ type BfIconButtonVariant = 'tonal' | 'primary' | 'outline' | 'text';
464
+ /** The class maps of bf-icon-button, shared with `bf-menu-button` (`@bitforgehq/ui/overlay`)
465
+ * through the internal `ɵBF_ICON_BUTTON_CLASSES` export so the two never drift. */
466
+ declare const ICON_BUTTON_CLASSES: {
467
+ readonly base: string;
468
+ readonly variant: Record<BfIconButtonVariant, string>;
469
+ readonly pressed: Record<BfIconButtonVariant, string>;
470
+ readonly size: Record<BfSize, string>;
471
+ };
472
+ /**
473
+ * Round button that holds a single icon, for toolbars, headers and list rows. The `label` is
474
+ * required because the icon alone gives assistive tech no name.
475
+ *
476
+ * @example
477
+ * <bf-icon-button label="Search" (clicked)="openSearch()">
478
+ * <bf-icon [icon]="Search" />
479
+ * </bf-icon-button>
480
+ * @summary Round icon-only button for toolbars and rows, with a required accessible label
481
+ * @category Actions
482
+ * @since 0.1.0
483
+ * @slot default The icon, a `bf-icon`.
484
+ */
485
+ export declare class BfIconButtonComponent {
486
+ /** Visual style: tonal (soft tint, default), primary, outline, text. */
487
+ readonly variant: import("@angular/core").InputSignal<BfIconButtonVariant>;
488
+ /** Height step: sm 32, md 40, lg 48 px (square); unset follows `provideBfDefaults()`
489
+ * (`controlSize`, `md` by default). */
490
+ readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
491
+ /** Native button type. */
492
+ readonly type: import("@angular/core").InputSignal<BfButtonType>;
493
+ /** Disables the control and swallows clicks. */
494
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
495
+ /** Accessible name announced instead of the icon. */
496
+ readonly label: import("@angular/core").InputSignal<string>;
497
+ /** Emitted on click while enabled. */
498
+ readonly clicked: import("@angular/core").OutputEmitterRef<Event>;
499
+ private readonly defaults;
500
+ /** The size in effect: `size`, else the app's `controlSize` default. */
501
+ protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
502
+ readonly classes: import("@angular/core").Signal<string>;
503
+ /**
504
+ * The inner button's click: emits `clicked` unless disabled.
505
+ * @internal
506
+ */
507
+ onClick(event: Event): void;
508
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfIconButtonComponent, never>;
509
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfIconButtonComponent, "bf-icon-button", never, {
510
+ "variant": {
511
+ "alias": "variant";
512
+ "required": false;
513
+ "isSignal": true;
514
+ };
515
+ "size": {
516
+ "alias": "size";
517
+ "required": false;
518
+ "isSignal": true;
519
+ };
520
+ "type": {
521
+ "alias": "type";
522
+ "required": false;
523
+ "isSignal": true;
524
+ };
525
+ "disabled": {
526
+ "alias": "disabled";
527
+ "required": false;
528
+ "isSignal": true;
529
+ };
530
+ "label": {
531
+ "alias": "label";
532
+ "required": true;
533
+ "isSignal": true;
534
+ };
535
+ }, {
536
+ "clicked": "clicked";
537
+ }, never, ["*"], true, never>;
538
+ }
539
+ /**
540
+ * The tone of a `bf-badge`: neutral, primary, success, warning or danger.
541
+ *
542
+ * @summary The five tones of a badge, from neutral counts to danger states
543
+ * @since 0.1.0
544
+ */
545
+ type BfBadgeVariant = 'neutral' | 'primary' | 'success' | 'warning' | 'danger';
546
+ /**
547
+ * Status label ("On track", "At risk") or, with `count`, a compact numeric pill for unread counts.
548
+ *
549
+ * @example
550
+ * <bf-badge variant="warning">At risk</bf-badge>
551
+ * <bf-badge [count]="unread()" countLabel="unread messages" />
552
+ * @summary Small status label in semantic tones, or a compact numeric pill for counts
553
+ * @category Data display
554
+ * @since 0.1.0
555
+ * @slot default The badge text, shown when no `count` is set.
556
+ */
557
+ export declare class BfBadgeComponent {
558
+ /** Tint for the label style. Ignored when `count` is set. */
559
+ readonly variant: import("@angular/core").InputSignal<BfBadgeVariant>;
560
+ /** Switches to the count pill; values above 99 render as "99+". */
561
+ readonly count: import("@angular/core").InputSignal<number | undefined>;
562
+ /** What the count counts ("unread messages"), read by assistive tech after the number ("99+
563
+ * unread messages"); visually hidden. Only used with `count`. */
564
+ readonly countLabel: import("@angular/core").InputSignal<string>;
565
+ readonly classes: import("@angular/core").Signal<string>;
566
+ readonly countText: import("@angular/core").Signal<string | null>;
567
+ readonly countClasses = "inline-flex h-box min-w-box items-center justify-center rounded-control bg-primary px-1.75 text-micro font-bold leading-none text-on-primary";
568
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfBadgeComponent, never>;
569
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfBadgeComponent, "bf-badge", never, {
570
+ "variant": {
571
+ "alias": "variant";
572
+ "required": false;
573
+ "isSignal": true;
574
+ };
575
+ "count": {
576
+ "alias": "count";
577
+ "required": false;
578
+ "isSignal": true;
579
+ };
580
+ "countLabel": {
581
+ "alias": "countLabel";
582
+ "required": false;
583
+ "isSignal": true;
584
+ };
585
+ }, {}, never, ["*"], true, never>;
586
+ }
587
+ /** A message paragraph that never moves the layout under a pressed pointer. */
588
+ interface HeldMessage {
589
+ /** The text to render: the current one, else (while pressed) the one still on screen. */
590
+ readonly text: Signal<string>;
591
+ /** Render it visually hidden (`sr-only`): a new message that arrived during the press. It is in
592
+ * the DOM at once, so the ids that point at it resolve and assistive tech reads it; it becomes
593
+ * visible, as the same element, once the press ends. */
594
+ readonly hidden: Signal<boolean>;
595
+ }
596
+ /**
597
+ * The paragraph state for a message `source` (an error text) under `heldWhilePressed`: a message
598
+ * that appears during a press renders at once but visually hidden; one that disappears stays
599
+ * visible until the press ends. Call it in an injection context.
600
+ */
601
+ declare function heldMessage(source: () => string): HeldMessage;
602
+ /**
603
+ * `source`, except that while a pointer button is held down anywhere in the document it keeps the
604
+ * value it had when the press began, and catches up once the press ends. Call it in an injection
605
+ * context (a component field initializer).
606
+ */
607
+ declare function heldWhilePressed<T>(source: () => T): Signal<T>;
608
+ /**
609
+ * Label, help text and error text around a form control, with the id wiring assistive tech needs.
610
+ * The form widgets use it internally; use it directly only to dress a custom control the same way.
611
+ *
612
+ * @example
613
+ * <bf-field #field label="Project name" helpText="Shown to your team" controlId="project">
614
+ * <input id="project" [class]="controlClass" [attr.aria-describedby]="field.describedBy()" />
615
+ * </bf-field>
616
+ * @summary Label, help text and error text wrapper that wires ids for assistive tech
617
+ * @category Forms
618
+ * @since 0.1.0
619
+ * @slot default The control the field labels, such as a native input styled with `bfFieldControlClass`.
620
+ */
621
+ export declare class BfFieldComponent {
622
+ /** Visible label; rendered as a `<label for>` pointing at `controlId`. */
623
+ readonly label: import("@angular/core").InputSignal<string>;
624
+ /** Helper text under the control; stays while `error` is shown. */
625
+ readonly helpText: import("@angular/core").InputSignal<string>;
626
+ /** Error text under the help text. One that appears while a pointer button is held down (the
627
+ * press on a Save button that blurred the field) renders visually hidden until the press ends,
628
+ * so assistive tech has it at once and the layout never moves under the pointer between
629
+ * mousedown and mouseup. */
630
+ readonly error: import("@angular/core").InputSignal<string>;
631
+ /** Adds the required marker to the label. */
632
+ readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
633
+ /** Dims the label; the control carries its own disabled styling. */
634
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
635
+ /** The id of the control inside the default slot. */
636
+ readonly controlId: import("@angular/core").InputSignal<string>;
637
+ readonly helpId: import("@angular/core").Signal<string>;
638
+ readonly errorId: import("@angular/core").Signal<string>;
639
+ /** The error paragraph: `error`, visually hidden while a press holds the layout. */
640
+ protected readonly message: HeldMessage;
641
+ /** Value for the control's `aria-describedby`: the help id and the error id, each while it is
642
+ * set (`"<id>-help <id>-error"`), else null; the paragraphs render whenever they are named. */
643
+ readonly describedBy: import("@angular/core").Signal<string | null>;
644
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfFieldComponent, never>;
645
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfFieldComponent, "bf-field", never, {
646
+ "label": {
647
+ "alias": "label";
648
+ "required": false;
649
+ "isSignal": true;
650
+ };
651
+ "helpText": {
652
+ "alias": "helpText";
653
+ "required": false;
654
+ "isSignal": true;
655
+ };
656
+ "error": {
657
+ "alias": "error";
658
+ "required": false;
659
+ "isSignal": true;
660
+ };
661
+ "required": {
662
+ "alias": "required";
663
+ "required": false;
664
+ "isSignal": true;
665
+ };
666
+ "disabled": {
667
+ "alias": "disabled";
668
+ "required": false;
669
+ "isSignal": true;
670
+ };
671
+ "controlId": {
672
+ "alias": "controlId";
673
+ "required": true;
674
+ "isSignal": true;
675
+ };
676
+ }, {}, never, ["*"], true, never>;
677
+ }
678
+ /** Field box: height and type per step (32 / 40 / 48 px). */
679
+ declare const FIELD_BOX: Record<BfSize, string>;
680
+ /** Inline-start padding of the text, without and with an `icon-start` slot. */
681
+ declare const FIELD_PADDING_START: Record<BfSize, Record<'text' | 'icon', string>>;
682
+ /** Inline-end padding of the text, without and with an `icon-end` slot. */
683
+ declare const FIELD_PADDING_END: Record<BfSize, Record<'text' | 'icon', string>>;
684
+ /** Inset of the `icon-start` slot from the field's inline-start edge. */
685
+ declare const FIELD_ICON_START: Record<BfSize, string>;
686
+ /** Inset of the `icon-end` slot from the field's inline-end edge. */
687
+ declare const FIELD_ICON_END: Record<BfSize, string>;
688
+ /** Box of a text-entry control: shape, border width, surface, focus ring and the native states. */
689
+ declare const FIELD_CONTROL_BASE: string;
690
+ /**
691
+ * The field state `bfFieldControlClass` styles a control for.
692
+ *
693
+ * @summary The size and state a custom field control is styled for by bfFieldControlClass
694
+ * @since 0.3.0
695
+ */
696
+ interface BfFieldControlState {
697
+ /** Height step: sm 32, md 40, lg 48 px, as `bf-input`'s `size`. */
698
+ size: BfSize;
699
+ /** Whether the control shows its error state (the danger border). */
700
+ invalid: boolean;
701
+ /** Whether the control is disabled; set the control's native `disabled` too. */
702
+ disabled: boolean;
703
+ /** Whether the control is read-only; set the control's native `readonly` too. */
704
+ readonly: boolean;
705
+ }
706
+ /**
707
+ * The class list `bf-input` puts on its native `<input>`, for a custom control inside `bf-field`
708
+ * (a native input with a mask, a combobox, a date picker's text box) that must look like the
709
+ * library's own fields: the same box, height and type per `size`, padding, focus ring and border,
710
+ * with the danger border while `invalid`. The disabled and read-only styles come from the
711
+ * control's native `disabled` / `readonly` attributes (`:disabled`, `:read-only`), so set those on
712
+ * the control as well; the class list is the one `bf-input` renders in the same state.
713
+ *
714
+ * @example
715
+ * <input [class]="controlClass()" [id]="id" [attr.aria-describedby]="field.describedBy()" />
716
+ * @param state The size and state to style the control for.
717
+ * @returns The class list, as one string for `[class]`.
718
+ * @summary The class list that makes a custom control look like a library text field
719
+ * @since 0.3.0
720
+ */
721
+ export declare function bfFieldControlClass(state: BfFieldControlState): string;
722
+ /**
723
+ * The native `type` of a `bf-input`; the value stays a string (for numbers, use `bf-number-input`).
724
+ *
725
+ * @summary The native input types a text field supports, all bound as strings
726
+ * @since 0.1.0
727
+ */
728
+ type BfInputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' | 'date' | 'time' | 'datetime-local' | 'month';
729
+ /**
730
+ * Native `inputmode`: the virtual keyboard a phone shows.
731
+ *
732
+ * @summary The virtual keyboards a phone can show for a text field
733
+ * @since 0.2.0
734
+ */
735
+ type BfInputMode = 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
736
+ /**
737
+ * Native `enterkeyhint`: the label of the virtual keyboard's Enter key.
738
+ *
739
+ * @summary The labels a phone keyboard can put on its Enter key
740
+ * @since 0.2.0
741
+ */
742
+ type BfEnterKeyHint = 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';
743
+ /**
744
+ * Native `autocapitalize`: how a virtual keyboard capitalises typed text.
745
+ *
746
+ * @summary How a phone keyboard capitalises the text typed into a field
747
+ * @since 0.2.0
748
+ */
749
+ type BfAutocapitalize = 'off' | 'none' | 'on' | 'sentences' | 'words' | 'characters';
750
+ /**
751
+ * The `inputMode` of a `bf-input`: a `BfInputMode`, or `''` (the default) to leave the native
752
+ * `inputmode` off.
753
+ *
754
+ * @summary A text field's virtual keyboard setting, a keyboard or empty to leave it off
755
+ * @since 0.3.0
756
+ */
757
+ type BfInputInputMode = BfInputMode | '';
758
+ /**
759
+ * The `enterKeyHint` of a `bf-input` or `bf-number-input`: a `BfEnterKeyHint`, or `''` (the
760
+ * default) to leave the native `enterkeyhint` off.
761
+ *
762
+ * @summary A field's Enter key label setting, a label or empty to leave it off
763
+ * @since 0.3.0
764
+ */
765
+ type BfInputEnterKeyHint = BfEnterKeyHint | '';
766
+ /**
767
+ * The `autocapitalize` of a `bf-input`: a `BfAutocapitalize`, or `''` (the default) to leave the
768
+ * native `autocapitalize` off.
769
+ *
770
+ * @summary A text field's capitalisation setting, a mode or empty to leave it off
771
+ * @since 0.3.0
772
+ */
773
+ type BfInputAutocapitalize = BfAutocapitalize | '';
774
+ /**
775
+ * The height step of a text field; the same scale as every sized widget.
776
+ *
777
+ * @deprecated 0.3.0 use BfSize; removed in 1.0.0
778
+ * @summary Former name of the shared size scale for text fields, kept until 1.0.0
779
+ * @since 0.1.0
780
+ */
781
+ type BfFieldSize = BfSize;
782
+ /**
783
+ * Single-line text field with label, help and error text, icon slots and Signal Forms binding.
784
+ * Bind `[(value)]` directly or `[formField]` from a signal form; the field state (touched,
785
+ * invalid, errors, disabled, readonly, required) flows in through the matching inputs.
786
+ *
787
+ * @example
788
+ * <bf-input label="Email" type="email" placeholder="name@company.ch" [(value)]="email" />
789
+ * <bf-input label="Email" [formField]="signup.email" />
790
+ * @summary Single-line text field with label, help and error text, icon slots and Signal Forms binding
791
+ * @category Forms
792
+ * @since 0.1.0
793
+ * @slot icon-start An icon inside the field, before the text.
794
+ * @slot icon-end An icon inside the field, after the text.
795
+ */
796
+ export declare class BfInputComponent implements FormValueControl<string> {
797
+ /** The text value; two-way bindable and bound by `[formField]`. */
798
+ readonly value: import("@angular/core").ModelSignal<string>;
799
+ /** Native input type; the value stays a string. For numbers use `bf-number-input`, which binds
800
+ * `number | null`. */
801
+ readonly type: import("@angular/core").InputSignal<BfInputType>;
802
+ /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`
803
+ * by default). */
804
+ readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
805
+ /** Visible label above the control. */
806
+ readonly label: import("@angular/core").InputSignal<string>;
807
+ /**
808
+ * Accessible name when no visible label is rendered (e.g. a search field). Ignored when `label`
809
+ * is set.
810
+ */
811
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
812
+ /**
813
+ * Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when
814
+ * `label` is set.
815
+ */
816
+ readonly ariaLabelledby: import("@angular/core").InputSignal<string>;
817
+ /** Example value shown while empty. */
818
+ readonly placeholder: import("@angular/core").InputSignal<string>;
819
+ /** Helper text under the control. */
820
+ readonly helpText: import("@angular/core").InputSignal<string>;
821
+ /** Explicit error text; takes precedence over Signal Forms errors. */
822
+ readonly errorMessage: import("@angular/core").InputSignal<string>;
823
+ /** Disables the control. */
824
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
825
+ /** Makes the control read-only. */
826
+ readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
827
+ /** Marks the control required (label marker and native attribute). */
828
+ readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
829
+ /** Field validity from Signal Forms. */
830
+ readonly invalid: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
831
+ /** Whether the user has left the field; errors show only once touched. */
832
+ readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
833
+ /** Validation errors from Signal Forms; the first message is shown once touched. */
834
+ readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
835
+ /** Native name attribute. */
836
+ readonly name: import("@angular/core").InputSignal<string>;
837
+ /** Control id; generated when not set. */
838
+ readonly id: import("@angular/core").InputSignal<string>;
839
+ /** Reserve space for an icon in the `icon-start` slot. */
840
+ readonly iconStart: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
841
+ /** Reserve space for an icon in the `icon-end` slot. */
842
+ readonly iconEnd: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
843
+ /** Native autocomplete hint. */
844
+ readonly autocomplete: import("@angular/core").InputSignal<string>;
845
+ /** Maximum number of characters (native `maxlength`); bound by Signal Forms `maxLength()`. */
846
+ readonly maxLength: import("@angular/core").InputSignal<number | undefined>;
847
+ /** Minimum number of characters (native `minlength`); bound by Signal Forms `minLength()`. */
848
+ readonly minLength: import("@angular/core").InputSignal<number | undefined>;
849
+ /** Lowest value (native `min`), e.g. `2026-01-01` for a date or `0` for a number. */
850
+ readonly min: import("@angular/core").InputSignal<string | undefined>;
851
+ /** Highest value (native `max`), e.g. `2026-12-31` for a date or `100` for a number. */
852
+ readonly max: import("@angular/core").InputSignal<string | undefined>;
853
+ /** Step between valid values (native `step`), e.g. `0.5` or `any`. */
854
+ readonly step: import("@angular/core").InputSignal<string | number | undefined>;
855
+ /**
856
+ * Patterns from Signal Forms `pattern()`; exactly one, with no flags or only `u`/`v`, is rendered
857
+ * as the native `pattern`.
858
+ */
859
+ readonly pattern: import("@angular/core").InputSignal<readonly RegExp[]>;
860
+ /** Virtual keyboard to show (native `inputmode`). */
861
+ readonly inputMode: import("@angular/core").InputSignal<BfInputInputMode>;
862
+ /** Label of the virtual keyboard's Enter key (native `enterkeyhint`). */
863
+ readonly enterKeyHint: import("@angular/core").InputSignal<BfInputEnterKeyHint>;
864
+ /** Spell checking on or off (native `spellcheck`); the browser decides while unset. */
865
+ readonly spellcheck: import("@angular/core").InputSignal<boolean | undefined>;
866
+ /** Capitalisation of typed text on virtual keyboards (native `autocapitalize`). */
867
+ readonly autocapitalize: import("@angular/core").InputSignal<BfInputAutocapitalize>;
868
+ /** Emitted with the new text right after the user changes it (each keystroke or paste). */
869
+ readonly changed: import("@angular/core").OutputEmitterRef<string>;
870
+ /** Emitted when the control gains focus. */
871
+ readonly focused: import("@angular/core").OutputEmitterRef<FocusEvent>;
872
+ /** Emitted when the control loses focus. */
873
+ readonly blurred: import("@angular/core").OutputEmitterRef<FocusEvent>;
874
+ /** Emitted on blur so Signal Forms marks the field touched. */
875
+ readonly touch: import("@angular/core").OutputEmitterRef<void>;
876
+ private readonly el;
877
+ private readonly labels;
878
+ private readonly defaults;
879
+ /** The size in effect: `size`, else the app's `fieldSize` default. */
880
+ protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
881
+ readonly iconStartClasses: import("@angular/core").Signal<string>;
882
+ readonly iconEndClasses: import("@angular/core").Signal<string>;
883
+ readonly errorText: import("@angular/core").Signal<string>;
884
+ readonly showError: import("@angular/core").Signal<boolean>;
885
+ readonly describedBy: import("@angular/core").Signal<string | null>;
886
+ /** `aria-errormessage`: the error paragraph while `aria-invalid` is set. */
887
+ readonly errorMessageId: import("@angular/core").Signal<string | null>;
888
+ /**
889
+ * `aria-label` value: only when there is no visible label, so the label stays the sole accessible
890
+ * name.
891
+ */
892
+ readonly ariaLabelAttr: import("@angular/core").Signal<string | null>;
893
+ /** `aria-labelledby` value, under the same rule as `ariaLabelAttr`. */
894
+ readonly ariaLabelledbyAttr: import("@angular/core").Signal<string | null>;
895
+ /**
896
+ * Native `pattern`: only an unambiguous single pattern whose flags HTML can honour (none, `u` or
897
+ * `v`; the browser compiles it anchored in `v` mode). Several patterns, or flags such as `i`,
898
+ * are validated by the form alone, so the native check never rejects a value the form accepts.
899
+ */
900
+ readonly patternAttr: import("@angular/core").Signal<string | null>;
901
+ readonly spellcheckAttr: import("@angular/core").Signal<string | null>;
902
+ readonly classes: import("@angular/core").Signal<string>;
903
+ /**
904
+ * Focuses the native input; Signal Forms calls it from `focusBoundControl()`.
905
+ * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.
906
+ */
907
+ focus(options?: FocusOptions): void;
908
+ /**
909
+ * Marks the field touched and emits `blurred`.
910
+ * @internal
911
+ */
912
+ onBlur(event: FocusEvent): void;
913
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfInputComponent, never>;
914
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfInputComponent, "bf-input", never, {
915
+ "value": {
916
+ "alias": "value";
917
+ "required": false;
918
+ "isSignal": true;
919
+ };
920
+ "type": {
921
+ "alias": "type";
922
+ "required": false;
923
+ "isSignal": true;
924
+ };
925
+ "size": {
926
+ "alias": "size";
927
+ "required": false;
928
+ "isSignal": true;
929
+ };
930
+ "label": {
931
+ "alias": "label";
932
+ "required": false;
933
+ "isSignal": true;
934
+ };
935
+ "ariaLabel": {
936
+ "alias": "ariaLabel";
937
+ "required": false;
938
+ "isSignal": true;
939
+ };
940
+ "ariaLabelledby": {
941
+ "alias": "ariaLabelledby";
942
+ "required": false;
943
+ "isSignal": true;
944
+ };
945
+ "placeholder": {
946
+ "alias": "placeholder";
947
+ "required": false;
948
+ "isSignal": true;
949
+ };
950
+ "helpText": {
951
+ "alias": "helpText";
952
+ "required": false;
953
+ "isSignal": true;
954
+ };
955
+ "errorMessage": {
956
+ "alias": "errorMessage";
957
+ "required": false;
958
+ "isSignal": true;
959
+ };
960
+ "disabled": {
961
+ "alias": "disabled";
962
+ "required": false;
963
+ "isSignal": true;
964
+ };
965
+ "readonly": {
966
+ "alias": "readonly";
967
+ "required": false;
968
+ "isSignal": true;
969
+ };
970
+ "required": {
971
+ "alias": "required";
972
+ "required": false;
973
+ "isSignal": true;
974
+ };
975
+ "invalid": {
976
+ "alias": "invalid";
977
+ "required": false;
978
+ "isSignal": true;
979
+ };
980
+ "touched": {
981
+ "alias": "touched";
982
+ "required": false;
983
+ "isSignal": true;
984
+ };
985
+ "errors": {
986
+ "alias": "errors";
987
+ "required": false;
988
+ "isSignal": true;
989
+ };
990
+ "name": {
991
+ "alias": "name";
992
+ "required": false;
993
+ "isSignal": true;
994
+ };
995
+ "id": {
996
+ "alias": "id";
997
+ "required": false;
998
+ "isSignal": true;
999
+ };
1000
+ "iconStart": {
1001
+ "alias": "iconStart";
1002
+ "required": false;
1003
+ "isSignal": true;
1004
+ };
1005
+ "iconEnd": {
1006
+ "alias": "iconEnd";
1007
+ "required": false;
1008
+ "isSignal": true;
1009
+ };
1010
+ "autocomplete": {
1011
+ "alias": "autocomplete";
1012
+ "required": false;
1013
+ "isSignal": true;
1014
+ };
1015
+ "maxLength": {
1016
+ "alias": "maxLength";
1017
+ "required": false;
1018
+ "isSignal": true;
1019
+ };
1020
+ "minLength": {
1021
+ "alias": "minLength";
1022
+ "required": false;
1023
+ "isSignal": true;
1024
+ };
1025
+ "min": {
1026
+ "alias": "min";
1027
+ "required": false;
1028
+ "isSignal": true;
1029
+ };
1030
+ "max": {
1031
+ "alias": "max";
1032
+ "required": false;
1033
+ "isSignal": true;
1034
+ };
1035
+ "step": {
1036
+ "alias": "step";
1037
+ "required": false;
1038
+ "isSignal": true;
1039
+ };
1040
+ "pattern": {
1041
+ "alias": "pattern";
1042
+ "required": false;
1043
+ "isSignal": true;
1044
+ };
1045
+ "inputMode": {
1046
+ "alias": "inputMode";
1047
+ "required": false;
1048
+ "isSignal": true;
1049
+ };
1050
+ "enterKeyHint": {
1051
+ "alias": "enterKeyHint";
1052
+ "required": false;
1053
+ "isSignal": true;
1054
+ };
1055
+ "spellcheck": {
1056
+ "alias": "spellcheck";
1057
+ "required": false;
1058
+ "isSignal": true;
1059
+ };
1060
+ "autocapitalize": {
1061
+ "alias": "autocapitalize";
1062
+ "required": false;
1063
+ "isSignal": true;
1064
+ };
1065
+ }, {
1066
+ "value": "valueChange";
1067
+ "changed": "changed";
1068
+ "focused": "focused";
1069
+ "blurred": "blurred";
1070
+ "touch": "touch";
1071
+ }, never, ["[bfSlot=icon-start]", "[bfSlot=icon-end]"], true, never>;
1072
+ }
1073
+ /**
1074
+ * Multi-line text field with the same chrome and Signal Forms binding as `bf-input`.
1075
+ *
1076
+ * @example
1077
+ * <bf-textarea label="Notes" [rows]="4" [(value)]="notes" />
1078
+ * @summary Multi-line text field with label, help and error text, and Signal Forms binding
1079
+ * @category Forms
1080
+ * @since 0.1.0
1081
+ */
1082
+ export declare class BfTextareaComponent implements FormValueControl<string> {
1083
+ /** The text value; two-way bindable and bound by `[formField]`. */
1084
+ readonly value: import("@angular/core").ModelSignal<string>;
1085
+ /** Padding and type step: sm, md, lg (a textarea's height comes from `rows`); unset follows
1086
+ * `provideBfDefaults()` (`fieldSize`, `md` by default). */
1087
+ readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
1088
+ /** Visible label above the control. */
1089
+ readonly label: import("@angular/core").InputSignal<string>;
1090
+ /**
1091
+ * Accessible name when no visible label is rendered (e.g. an inline comment box). Ignored when
1092
+ * `label` is set.
1093
+ */
1094
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
1095
+ /**
1096
+ * Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when
1097
+ * `label` is set.
1098
+ */
1099
+ readonly ariaLabelledby: import("@angular/core").InputSignal<string>;
1100
+ /** Example value shown while empty. */
1101
+ readonly placeholder: import("@angular/core").InputSignal<string>;
1102
+ /** Helper text under the control. */
1103
+ readonly helpText: import("@angular/core").InputSignal<string>;
1104
+ /** Explicit error text; takes precedence over Signal Forms errors. */
1105
+ readonly errorMessage: import("@angular/core").InputSignal<string>;
1106
+ /** Disables the control. */
1107
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1108
+ /** Makes the control read-only. */
1109
+ readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1110
+ /** Marks the control required. */
1111
+ readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1112
+ /** Field validity from Signal Forms. */
1113
+ readonly invalid: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1114
+ /** Whether the user has left the field. */
1115
+ readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1116
+ /** Validation errors from Signal Forms. */
1117
+ readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
1118
+ /** Native name attribute. */
1119
+ readonly name: import("@angular/core").InputSignal<string>;
1120
+ /** Control id; generated when not set. */
1121
+ readonly id: import("@angular/core").InputSignal<string>;
1122
+ /** Visible rows; with `autoResize`, the rows the empty box starts at. */
1123
+ readonly rows: import("@angular/core").InputSignal<number>;
1124
+ /** Grows with the content (CSS `field-sizing: content`) from `rows` up to `maxRows`. Where the
1125
+ * browser has no `field-sizing` it keeps the fixed `rows`. */
1126
+ readonly autoResize: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1127
+ /** With `autoResize`, the rows the box grows to at most; past them it scrolls. Unset, it grows
1128
+ * without a bound. */
1129
+ readonly maxRows: import("@angular/core").InputSignal<number | undefined>;
1130
+ /** Maximum number of characters (native `maxlength`); bound by Signal Forms `maxLength()`. */
1131
+ readonly maxLength: import("@angular/core").InputSignal<number | undefined>;
1132
+ /** Minimum number of characters (native `minlength`); bound by Signal Forms `minLength()`. */
1133
+ readonly minLength: import("@angular/core").InputSignal<number | undefined>;
1134
+ /** Emitted with the new text right after the user changes it (each keystroke or paste). */
1135
+ readonly changed: import("@angular/core").OutputEmitterRef<string>;
1136
+ /** Emitted when the control gains focus. */
1137
+ readonly focused: import("@angular/core").OutputEmitterRef<FocusEvent>;
1138
+ /** Emitted when the control loses focus. */
1139
+ readonly blurred: import("@angular/core").OutputEmitterRef<FocusEvent>;
1140
+ /** Emitted on blur so Signal Forms marks the field touched. */
1141
+ readonly touch: import("@angular/core").OutputEmitterRef<void>;
1142
+ private readonly el;
1143
+ private readonly labels;
1144
+ private readonly defaults;
1145
+ /** The size in effect: `size`, else the app's `fieldSize` default. */
1146
+ protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
1147
+ /** Whether the browser sizes a field to its content; read once. False on the server and where
1148
+ * `CSS.supports` is missing, so the box keeps its fixed `rows` there. */
1149
+ private readonly fieldSizing;
1150
+ /** Auto-resize in effect: asked for, and the browser can do it. */
1151
+ private readonly growing;
1152
+ /** The height of `n` lines of this step, padding and border included. */
1153
+ private blockSize;
1154
+ /** While growing: the empty box is as tall as `rows` lines. */
1155
+ protected readonly minBlockSize: import("@angular/core").Signal<string | null>;
1156
+ /** While growing with `maxRows`: it stops at `maxRows` lines. */
1157
+ protected readonly maxBlockSize: import("@angular/core").Signal<string | null>;
1158
+ readonly errorText: import("@angular/core").Signal<string>;
1159
+ readonly showError: import("@angular/core").Signal<boolean>;
1160
+ readonly describedBy: import("@angular/core").Signal<string | null>;
1161
+ /** `aria-errormessage`: the error paragraph while `aria-invalid` is set. */
1162
+ readonly errorMessageId: import("@angular/core").Signal<string | null>;
1163
+ /**
1164
+ * `aria-label` value: only when there is no visible label, so the label stays the sole accessible
1165
+ * name.
1166
+ */
1167
+ readonly ariaLabelAttr: import("@angular/core").Signal<string | null>;
1168
+ /** `aria-labelledby` value, under the same rule as `ariaLabelAttr`. */
1169
+ readonly ariaLabelledbyAttr: import("@angular/core").Signal<string | null>;
1170
+ readonly classes: import("@angular/core").Signal<string>;
1171
+ /**
1172
+ * Focuses the native textarea; Signal Forms calls it from `focusBoundControl()`.
1173
+ * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.
1174
+ */
1175
+ focus(options?: FocusOptions): void;
1176
+ /**
1177
+ * Marks the field touched and emits `blurred`.
1178
+ * @internal
1179
+ */
1180
+ onBlur(event: FocusEvent): void;
1181
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfTextareaComponent, never>;
1182
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfTextareaComponent, "bf-textarea", never, {
1183
+ "value": {
1184
+ "alias": "value";
1185
+ "required": false;
1186
+ "isSignal": true;
1187
+ };
1188
+ "size": {
1189
+ "alias": "size";
1190
+ "required": false;
1191
+ "isSignal": true;
1192
+ };
1193
+ "label": {
1194
+ "alias": "label";
1195
+ "required": false;
1196
+ "isSignal": true;
1197
+ };
1198
+ "ariaLabel": {
1199
+ "alias": "ariaLabel";
1200
+ "required": false;
1201
+ "isSignal": true;
1202
+ };
1203
+ "ariaLabelledby": {
1204
+ "alias": "ariaLabelledby";
1205
+ "required": false;
1206
+ "isSignal": true;
1207
+ };
1208
+ "placeholder": {
1209
+ "alias": "placeholder";
1210
+ "required": false;
1211
+ "isSignal": true;
1212
+ };
1213
+ "helpText": {
1214
+ "alias": "helpText";
1215
+ "required": false;
1216
+ "isSignal": true;
1217
+ };
1218
+ "errorMessage": {
1219
+ "alias": "errorMessage";
1220
+ "required": false;
1221
+ "isSignal": true;
1222
+ };
1223
+ "disabled": {
1224
+ "alias": "disabled";
1225
+ "required": false;
1226
+ "isSignal": true;
1227
+ };
1228
+ "readonly": {
1229
+ "alias": "readonly";
1230
+ "required": false;
1231
+ "isSignal": true;
1232
+ };
1233
+ "required": {
1234
+ "alias": "required";
1235
+ "required": false;
1236
+ "isSignal": true;
1237
+ };
1238
+ "invalid": {
1239
+ "alias": "invalid";
1240
+ "required": false;
1241
+ "isSignal": true;
1242
+ };
1243
+ "touched": {
1244
+ "alias": "touched";
1245
+ "required": false;
1246
+ "isSignal": true;
1247
+ };
1248
+ "errors": {
1249
+ "alias": "errors";
1250
+ "required": false;
1251
+ "isSignal": true;
1252
+ };
1253
+ "name": {
1254
+ "alias": "name";
1255
+ "required": false;
1256
+ "isSignal": true;
1257
+ };
1258
+ "id": {
1259
+ "alias": "id";
1260
+ "required": false;
1261
+ "isSignal": true;
1262
+ };
1263
+ "rows": {
1264
+ "alias": "rows";
1265
+ "required": false;
1266
+ "isSignal": true;
1267
+ };
1268
+ "autoResize": {
1269
+ "alias": "autoResize";
1270
+ "required": false;
1271
+ "isSignal": true;
1272
+ };
1273
+ "maxRows": {
1274
+ "alias": "maxRows";
1275
+ "required": false;
1276
+ "isSignal": true;
1277
+ };
1278
+ "maxLength": {
1279
+ "alias": "maxLength";
1280
+ "required": false;
1281
+ "isSignal": true;
1282
+ };
1283
+ "minLength": {
1284
+ "alias": "minLength";
1285
+ "required": false;
1286
+ "isSignal": true;
1287
+ };
1288
+ }, {
1289
+ "value": "valueChange";
1290
+ "changed": "changed";
1291
+ "focused": "focused";
1292
+ "blurred": "blurred";
1293
+ "touch": "touch";
1294
+ }, never, never, true, never>;
1295
+ }
1296
+ /**
1297
+ * Equality that matches a bound value to an option's value (`compareWith` of the choice controls).
1298
+ * Called as `compareWith(optionValue, value)`: the option's value first, the bound value second.
1299
+ *
1300
+ * @summary Equality of choice values, for options that are objects rather than primitives
1301
+ * @since 0.3.0
1302
+ */
1303
+ type BfCompareWith<T> = (optionValue: T, value: T) => boolean;
1304
+ /**
1305
+ * Index of the option whose value matches `value` under `compare`; `-1` for `null` (nothing
1306
+ * selected) or a value no option matches. An option whose value is `null` therefore never shows as
1307
+ * selected.
1308
+ */
1309
+ declare function choiceIndex<T>(options: readonly {
1310
+ readonly value: T;
1311
+ }[], value: T | null, compare: BfCompareWith<T>): number;
1312
+ /**
1313
+ * The native `value` of an option (`<option>`, radio): `String(value)` for a string, number or
1314
+ * boolean, so native reads, form posts and browser tests see the real value; the option index for
1315
+ * anything else (objects). The controls map a choice back by position, never by this key, so
1316
+ * duplicate keys still resolve to the right option.
1317
+ */
1318
+ declare function choiceKey(value: unknown, index: number): string;
1319
+ /**
1320
+ * One choice of `bf-select`; `value` is any type (a string by default).
1321
+ *
1322
+ * @summary One choice of a select with its value, its label and a disabled flag
1323
+ * @since 0.1.0
1324
+ */
1325
+ interface BfSelectOption<T = string> {
1326
+ /** The value the select's `value` takes when this option is chosen. */
1327
+ value: T;
1328
+ /** The text of the native `option`. */
1329
+ label: string;
1330
+ /** Whether this option cannot be chosen. */
1331
+ disabled?: boolean;
1332
+ }
1333
+ /**
1334
+ * Native single-choice dropdown styled like the text field, with a placeholder option and
1335
+ * Signal Forms binding. Generic over the option value (a string by default); `null` means nothing
1336
+ * is selected.
1337
+ *
1338
+ * @example
1339
+ * <bf-select label="Project" placeholder="Pick a project" [options]="projects" [(value)]="projectId" />
1340
+ * <bf-select label="Team" placeholder="Pick a team" [options]="teams" [formField]="task.teamId" />
1341
+ * @summary Native single-choice dropdown styled like the text field, with Signal Forms binding
1342
+ * @category Forms
1343
+ * @since 0.1.0
1344
+ */
1345
+ export declare class BfSelectComponent<T = string> implements FormValueControl<T | null> {
1346
+ /** The selected option's value, `null` while nothing is selected; two-way bindable and bound by
1347
+ * `[formField]`. */
1348
+ readonly value: import("@angular/core").ModelSignal<T | null>;
1349
+ /** The options to choose from. */
1350
+ readonly options: import("@angular/core").InputSignal<readonly BfSelectOption<T>[]>;
1351
+ /** Equality for matching `value` to an option (default `Object.is`); pass one for object values. */
1352
+ readonly compareWith: import("@angular/core").InputSignal<BfCompareWith<T>>;
1353
+ /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md`
1354
+ * by default). */
1355
+ readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
1356
+ /** Visible label above the control. */
1357
+ readonly label: import("@angular/core").InputSignal<string>;
1358
+ /**
1359
+ * Accessible name when no visible label is rendered (e.g. a table filter). Ignored when `label`
1360
+ * is set.
1361
+ */
1362
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
1363
+ /**
1364
+ * Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when
1365
+ * `label` is set.
1366
+ */
1367
+ readonly ariaLabelledby: import("@angular/core").InputSignal<string>;
1368
+ /** Disabled first option shown while nothing is selected. */
1369
+ readonly placeholder: import("@angular/core").InputSignal<string>;
1370
+ /** Helper text under the control. */
1371
+ readonly helpText: import("@angular/core").InputSignal<string>;
1372
+ /** Explicit error text; takes precedence over Signal Forms errors. */
1373
+ readonly errorMessage: import("@angular/core").InputSignal<string>;
1374
+ /** Disables the control. */
1375
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1376
+ /** Shows the value but blocks changes; the select stays focusable and exposes `aria-readonly`. */
1377
+ readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1378
+ /** Marks the control required. */
1379
+ readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1380
+ /** Field validity from Signal Forms. */
1381
+ readonly invalid: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1382
+ /** Whether the user has left the field. */
1383
+ readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1384
+ /** Validation errors from Signal Forms. */
1385
+ readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
1386
+ /** Native name attribute. */
1387
+ readonly name: import("@angular/core").InputSignal<string>;
1388
+ /** Control id; generated when not set. */
1389
+ readonly id: import("@angular/core").InputSignal<string>;
1390
+ /** Emitted with the chosen value after a user change (never `null`). */
1391
+ readonly changed: import("@angular/core").OutputEmitterRef<T>;
1392
+ /** Emitted when the control gains focus. */
1393
+ readonly focused: import("@angular/core").OutputEmitterRef<FocusEvent>;
1394
+ /** Emitted when the control loses focus. */
1395
+ readonly blurred: import("@angular/core").OutputEmitterRef<FocusEvent>;
1396
+ /** Emitted on blur so Signal Forms marks the field touched. */
1397
+ readonly touch: import("@angular/core").OutputEmitterRef<void>;
1398
+ private readonly el;
1399
+ private readonly defaults;
1400
+ /** The size in effect: `size`, else the app's `fieldSize` default. */
1401
+ protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
1402
+ readonly wrapperClasses: import("@angular/core").Signal<string>;
1403
+ /** Index of the option matching `value`, `-1` while nothing (or `null`) is selected. */
1404
+ readonly selectedIndex: import("@angular/core").Signal<number>;
1405
+ readonly showEmptyOption: import("@angular/core").Signal<boolean>;
1406
+ private readonly labels;
1407
+ readonly errorText: import("@angular/core").Signal<string>;
1408
+ readonly showError: import("@angular/core").Signal<boolean>;
1409
+ readonly describedBy: import("@angular/core").Signal<string | null>;
1410
+ /** `aria-errormessage`: the error paragraph while `aria-invalid` is set. */
1411
+ readonly errorMessageId: import("@angular/core").Signal<string | null>;
1412
+ /**
1413
+ * `aria-label` value: only when there is no visible label, so the label stays the sole accessible
1414
+ * name.
1415
+ */
1416
+ readonly ariaLabelAttr: import("@angular/core").Signal<string | null>;
1417
+ /** `aria-labelledby` value, under the same rule as `ariaLabelAttr`. */
1418
+ readonly ariaLabelledbyAttr: import("@angular/core").Signal<string | null>;
1419
+ readonly classes: import("@angular/core").Signal<string>;
1420
+ /** Native `value` of an option: its value for a primitive, its index for an object. */
1421
+ protected readonly key: typeof choiceKey;
1422
+ /**
1423
+ * Focuses the native select; Signal Forms calls it from `focusBoundControl()`.
1424
+ * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.
1425
+ */
1426
+ focus(options?: FocusOptions): void;
1427
+ /**
1428
+ * Read-only: no picker on a mouse press. Cancelling the press also cancels its focus, so the
1429
+ * select is focused explicitly, like any other read-only control. Touch screens open the
1430
+ * platform picker without a cancellable press; a choice made there is reverted by `onChange`.
1431
+ * @internal
1432
+ */
1433
+ onMousedown(event: MouseEvent): void;
1434
+ /**
1435
+ * Read-only: no picker or value change from the keyboard (arrows, Enter, Space, F4, type-ahead).
1436
+ * @internal
1437
+ */
1438
+ onKeydown(event: KeyboardEvent): void;
1439
+ /**
1440
+ * Writes the chosen option's value to the model and emits `changed`; while read-only, restores
1441
+ * the shown option instead.
1442
+ * @internal
1443
+ */
1444
+ onChange(el: HTMLSelectElement): void;
1445
+ /**
1446
+ * Marks the field touched and emits `blurred`.
1447
+ * @internal
1448
+ */
1449
+ onBlur(event: FocusEvent): void;
1450
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfSelectComponent<any>, never>;
1451
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfSelectComponent<any>, "bf-select", never, {
1452
+ "value": {
1453
+ "alias": "value";
1454
+ "required": false;
1455
+ "isSignal": true;
1456
+ };
1457
+ "options": {
1458
+ "alias": "options";
1459
+ "required": true;
1460
+ "isSignal": true;
1461
+ };
1462
+ "compareWith": {
1463
+ "alias": "compareWith";
1464
+ "required": false;
1465
+ "isSignal": true;
1466
+ };
1467
+ "size": {
1468
+ "alias": "size";
1469
+ "required": false;
1470
+ "isSignal": true;
1471
+ };
1472
+ "label": {
1473
+ "alias": "label";
1474
+ "required": false;
1475
+ "isSignal": true;
1476
+ };
1477
+ "ariaLabel": {
1478
+ "alias": "ariaLabel";
1479
+ "required": false;
1480
+ "isSignal": true;
1481
+ };
1482
+ "ariaLabelledby": {
1483
+ "alias": "ariaLabelledby";
1484
+ "required": false;
1485
+ "isSignal": true;
1486
+ };
1487
+ "placeholder": {
1488
+ "alias": "placeholder";
1489
+ "required": false;
1490
+ "isSignal": true;
1491
+ };
1492
+ "helpText": {
1493
+ "alias": "helpText";
1494
+ "required": false;
1495
+ "isSignal": true;
1496
+ };
1497
+ "errorMessage": {
1498
+ "alias": "errorMessage";
1499
+ "required": false;
1500
+ "isSignal": true;
1501
+ };
1502
+ "disabled": {
1503
+ "alias": "disabled";
1504
+ "required": false;
1505
+ "isSignal": true;
1506
+ };
1507
+ "readonly": {
1508
+ "alias": "readonly";
1509
+ "required": false;
1510
+ "isSignal": true;
1511
+ };
1512
+ "required": {
1513
+ "alias": "required";
1514
+ "required": false;
1515
+ "isSignal": true;
1516
+ };
1517
+ "invalid": {
1518
+ "alias": "invalid";
1519
+ "required": false;
1520
+ "isSignal": true;
1521
+ };
1522
+ "touched": {
1523
+ "alias": "touched";
1524
+ "required": false;
1525
+ "isSignal": true;
1526
+ };
1527
+ "errors": {
1528
+ "alias": "errors";
1529
+ "required": false;
1530
+ "isSignal": true;
1531
+ };
1532
+ "name": {
1533
+ "alias": "name";
1534
+ "required": false;
1535
+ "isSignal": true;
1536
+ };
1537
+ "id": {
1538
+ "alias": "id";
1539
+ "required": false;
1540
+ "isSignal": true;
1541
+ };
1542
+ }, {
1543
+ "value": "valueChange";
1544
+ "changed": "changed";
1545
+ "focused": "focused";
1546
+ "blurred": "blurred";
1547
+ "touch": "touch";
1548
+ }, never, never, true, never>;
1549
+ }
1550
+ /**
1551
+ * Checkbox with a 22 px rounded box and an optional label, implementing the Signal Forms
1552
+ * checkbox contract so `[formField]` binds `checked`.
1553
+ *
1554
+ * @example
1555
+ * <bf-checkbox [(checked)]="agree">I agree to the terms</bf-checkbox>
1556
+ * <bf-checkbox label="Notify me" [formField]="prefs.notify" />
1557
+ * @summary Rounded checkbox with an optional label that binds to Signal Forms
1558
+ * @category Forms
1559
+ * @since 0.1.0
1560
+ * @slot default Rich label content next to the box, before the `label` text.
1561
+ */
1562
+ export declare class BfCheckboxComponent implements FormCheckboxControl {
1563
+ /** Whether the box is checked; two-way bindable and bound by `[formField]`. */
1564
+ readonly checked: import("@angular/core").ModelSignal<boolean>;
1565
+ /** Label text; the default slot works too. */
1566
+ readonly label: import("@angular/core").InputSignal<string>;
1567
+ /** Accessible name when there is no visible `label`, e.g. a row-selection box. */
1568
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
1569
+ /** Id(s) of the element(s) that name the control when no visible label is rendered (e.g. a
1570
+ * table column header). */
1571
+ readonly ariaLabelledby: import("@angular/core").InputSignal<string>;
1572
+ /** Height step of the row: sm 32, md 40, lg 48 px (44 px under a coarse pointer for sm and md);
1573
+ * unset follows `provideBfDefaults()` (`controlSize`, `md` by default). */
1574
+ readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
1575
+ /** Shows the mixed state (e.g. "select all" with some rows selected); two-way bindable. A user
1576
+ * change clears it, like the native checkbox, so the box and `aria-checked` agree. */
1577
+ readonly indeterminate: import("@angular/core").ModelSignal<boolean>;
1578
+ /** Disables the control. */
1579
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1580
+ /** Shows the state but blocks changes; the box stays focusable and exposes `aria-readonly`. */
1581
+ readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1582
+ /** Marks the control required. */
1583
+ readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1584
+ /** Field validity from Signal Forms. */
1585
+ readonly invalid: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1586
+ /** Whether the user has left the field. */
1587
+ readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1588
+ /** Validation errors from Signal Forms. */
1589
+ readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
1590
+ /** Explicit error text; takes precedence over Signal Forms errors. */
1591
+ readonly errorMessage: import("@angular/core").InputSignal<string>;
1592
+ /** Native name attribute. */
1593
+ readonly name: import("@angular/core").InputSignal<string>;
1594
+ /** Control id; generated when not set. */
1595
+ readonly id: import("@angular/core").InputSignal<string>;
1596
+ /** Emitted with the new checked state after a user change. */
1597
+ readonly changed: import("@angular/core").OutputEmitterRef<boolean>;
1598
+ /** Emitted on blur so Signal Forms marks the field touched. */
1599
+ readonly touch: import("@angular/core").OutputEmitterRef<void>;
1600
+ private readonly el;
1601
+ private readonly labels;
1602
+ private readonly defaults;
1603
+ /** The size in effect: `size`, else the app's `controlSize` default. */
1604
+ protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
1605
+ readonly errorText: import("@angular/core").Signal<string>;
1606
+ readonly showError: import("@angular/core").Signal<boolean>;
1607
+ /** The error paragraph: `errorText`, visually hidden while a press elsewhere (that blurred
1608
+ * this control) holds the layout, so it never moves under the pointer. */
1609
+ protected readonly message: HeldMessage;
1610
+ /** The id of the error paragraph (`aria-describedby`) while there is an error, else null; the
1611
+ * paragraph renders whenever it is named. */
1612
+ protected readonly errorId: import("@angular/core").Signal<string | null>;
1613
+ private readonly mode;
1614
+ readonly labelClasses: import("@angular/core").Signal<string>;
1615
+ readonly textClasses: import("@angular/core").Signal<string>;
1616
+ readonly errorClasses: import("@angular/core").Signal<string>;
1617
+ readonly boxClasses: import("@angular/core").Signal<string>;
1618
+ /**
1619
+ * Focuses the native checkbox; Signal Forms calls it from `focusBoundControl()`.
1620
+ * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.
1621
+ */
1622
+ focus(options?: FocusOptions): void;
1623
+ /**
1624
+ * Read-only: cancels the toggle. Space activates a checkbox through a click, so this covers it.
1625
+ * @internal
1626
+ */
1627
+ onClick(event: MouseEvent): void;
1628
+ /**
1629
+ * Writes the native checkbox state to `checked` and emits `changed`.
1630
+ * @internal
1631
+ */
1632
+ onChange(next: boolean): void;
1633
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfCheckboxComponent, never>;
1634
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfCheckboxComponent, "bf-checkbox", never, {
1635
+ "checked": {
1636
+ "alias": "checked";
1637
+ "required": false;
1638
+ "isSignal": true;
1639
+ };
1640
+ "label": {
1641
+ "alias": "label";
1642
+ "required": false;
1643
+ "isSignal": true;
1644
+ };
1645
+ "ariaLabel": {
1646
+ "alias": "ariaLabel";
1647
+ "required": false;
1648
+ "isSignal": true;
1649
+ };
1650
+ "ariaLabelledby": {
1651
+ "alias": "ariaLabelledby";
1652
+ "required": false;
1653
+ "isSignal": true;
1654
+ };
1655
+ "size": {
1656
+ "alias": "size";
1657
+ "required": false;
1658
+ "isSignal": true;
1659
+ };
1660
+ "indeterminate": {
1661
+ "alias": "indeterminate";
1662
+ "required": false;
1663
+ "isSignal": true;
1664
+ };
1665
+ "disabled": {
1666
+ "alias": "disabled";
1667
+ "required": false;
1668
+ "isSignal": true;
1669
+ };
1670
+ "readonly": {
1671
+ "alias": "readonly";
1672
+ "required": false;
1673
+ "isSignal": true;
1674
+ };
1675
+ "required": {
1676
+ "alias": "required";
1677
+ "required": false;
1678
+ "isSignal": true;
1679
+ };
1680
+ "invalid": {
1681
+ "alias": "invalid";
1682
+ "required": false;
1683
+ "isSignal": true;
1684
+ };
1685
+ "touched": {
1686
+ "alias": "touched";
1687
+ "required": false;
1688
+ "isSignal": true;
1689
+ };
1690
+ "errors": {
1691
+ "alias": "errors";
1692
+ "required": false;
1693
+ "isSignal": true;
1694
+ };
1695
+ "errorMessage": {
1696
+ "alias": "errorMessage";
1697
+ "required": false;
1698
+ "isSignal": true;
1699
+ };
1700
+ "name": {
1701
+ "alias": "name";
1702
+ "required": false;
1703
+ "isSignal": true;
1704
+ };
1705
+ "id": {
1706
+ "alias": "id";
1707
+ "required": false;
1708
+ "isSignal": true;
1709
+ };
1710
+ }, {
1711
+ "checked": "checkedChange";
1712
+ "indeterminate": "indeterminateChange";
1713
+ "changed": "changed";
1714
+ "touch": "touch";
1715
+ }, never, ["*"], true, never>;
1716
+ }
1717
+ /**
1718
+ * The side of a `bf-toggle`'s switch its label sits on: after it (`end`) or before it (`start`).
1719
+ *
1720
+ * @summary Whether a toggle's label sits after or before its switch
1721
+ * @since 0.3.0
1722
+ */
1723
+ type BfToggleLabelPosition = 'end' | 'start';
1724
+ /**
1725
+ * On/off switch for settings that apply immediately. Implements the Signal Forms checkbox contract.
1726
+ *
1727
+ * @example
1728
+ * <bf-toggle label="Notifications" [(checked)]="notifications" />
1729
+ * @summary On/off switch for settings that apply immediately, with Signal Forms binding
1730
+ * @category Forms
1731
+ * @since 0.1.0
1732
+ * @slot default Rich label content after the `label` text.
1733
+ */
1734
+ export declare class BfToggleComponent implements FormCheckboxControl {
1735
+ /** Whether the switch is on; two-way bindable and bound by `[formField]`. */
1736
+ readonly checked: import("@angular/core").ModelSignal<boolean>;
1737
+ /** Label text; the default slot works too. */
1738
+ readonly label: import("@angular/core").InputSignal<string>;
1739
+ /** Accessible name when no visible label is rendered (e.g. a switch in a list row). */
1740
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
1741
+ /** Id(s) of the element(s) that name the control when no visible label is rendered (e.g. a
1742
+ * table column header). */
1743
+ readonly ariaLabelledby: import("@angular/core").InputSignal<string>;
1744
+ /** Height step of the row: sm 32, md 40, lg 48 px (44 px under a coarse pointer for sm and md);
1745
+ * unset follows `provideBfDefaults()` (`controlSize`, `md` by default). */
1746
+ readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
1747
+ /** Put the label before the switch (as in settings lists). */
1748
+ readonly labelPosition: import("@angular/core").InputSignal<BfToggleLabelPosition>;
1749
+ /** Disables the control. */
1750
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1751
+ /** Shows the state but blocks changes; the switch stays focusable and exposes `aria-readonly`. */
1752
+ readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1753
+ /** Marks the control required. */
1754
+ readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1755
+ /** Field validity from Signal Forms. */
1756
+ readonly invalid: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1757
+ /** Whether the user has left the field. */
1758
+ readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1759
+ /** Validation errors from Signal Forms. */
1760
+ readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
1761
+ /** Explicit error text; takes precedence over Signal Forms errors. */
1762
+ readonly errorMessage: import("@angular/core").InputSignal<string>;
1763
+ /** Native name attribute. */
1764
+ readonly name: import("@angular/core").InputSignal<string>;
1765
+ /** Control id; generated when not set. */
1766
+ readonly id: import("@angular/core").InputSignal<string>;
1767
+ /** Emitted with the new state after a user change. */
1768
+ readonly changed: import("@angular/core").OutputEmitterRef<boolean>;
1769
+ /** Emitted on blur so Signal Forms marks the field touched. */
1770
+ readonly touch: import("@angular/core").OutputEmitterRef<void>;
1771
+ private readonly el;
1772
+ private readonly defaults;
1773
+ /** The size in effect: `size`, else the app's `controlSize` default. */
1774
+ protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
1775
+ private readonly mode;
1776
+ readonly labelClasses: import("@angular/core").Signal<string>;
1777
+ readonly trackClasses: import("@angular/core").Signal<string>;
1778
+ readonly textClasses: import("@angular/core").Signal<string>;
1779
+ readonly knobClasses: import("@angular/core").Signal<string>;
1780
+ private readonly labels;
1781
+ readonly errorText: import("@angular/core").Signal<string>;
1782
+ readonly showError: import("@angular/core").Signal<boolean>;
1783
+ /** The error paragraph: `errorText`, visually hidden while a press elsewhere (that blurred
1784
+ * this control) holds the layout, so it never moves under the pointer. */
1785
+ protected readonly message: HeldMessage;
1786
+ /** The id of the error paragraph (`aria-describedby`) while there is an error, else null; the
1787
+ * paragraph renders whenever it is named. */
1788
+ protected readonly errorId: import("@angular/core").Signal<string | null>;
1789
+ /**
1790
+ * Focuses the native switch; Signal Forms calls it from `focusBoundControl()`.
1791
+ * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.
1792
+ */
1793
+ focus(options?: FocusOptions): void;
1794
+ /**
1795
+ * Read-only: cancels the toggle. Space activates a switch through a click, so this covers it.
1796
+ * @internal
1797
+ */
1798
+ onClick(event: MouseEvent): void;
1799
+ /**
1800
+ * Writes the native switch state to `checked` and emits `changed`.
1801
+ * @internal
1802
+ */
1803
+ onChange(next: boolean): void;
1804
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfToggleComponent, never>;
1805
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfToggleComponent, "bf-toggle", never, {
1806
+ "checked": {
1807
+ "alias": "checked";
1808
+ "required": false;
1809
+ "isSignal": true;
1810
+ };
1811
+ "label": {
1812
+ "alias": "label";
1813
+ "required": false;
1814
+ "isSignal": true;
1815
+ };
1816
+ "ariaLabel": {
1817
+ "alias": "ariaLabel";
1818
+ "required": false;
1819
+ "isSignal": true;
1820
+ };
1821
+ "ariaLabelledby": {
1822
+ "alias": "ariaLabelledby";
1823
+ "required": false;
1824
+ "isSignal": true;
1825
+ };
1826
+ "size": {
1827
+ "alias": "size";
1828
+ "required": false;
1829
+ "isSignal": true;
1830
+ };
1831
+ "labelPosition": {
1832
+ "alias": "labelPosition";
1833
+ "required": false;
1834
+ "isSignal": true;
1835
+ };
1836
+ "disabled": {
1837
+ "alias": "disabled";
1838
+ "required": false;
1839
+ "isSignal": true;
1840
+ };
1841
+ "readonly": {
1842
+ "alias": "readonly";
1843
+ "required": false;
1844
+ "isSignal": true;
1845
+ };
1846
+ "required": {
1847
+ "alias": "required";
1848
+ "required": false;
1849
+ "isSignal": true;
1850
+ };
1851
+ "invalid": {
1852
+ "alias": "invalid";
1853
+ "required": false;
1854
+ "isSignal": true;
1855
+ };
1856
+ "touched": {
1857
+ "alias": "touched";
1858
+ "required": false;
1859
+ "isSignal": true;
1860
+ };
1861
+ "errors": {
1862
+ "alias": "errors";
1863
+ "required": false;
1864
+ "isSignal": true;
1865
+ };
1866
+ "errorMessage": {
1867
+ "alias": "errorMessage";
1868
+ "required": false;
1869
+ "isSignal": true;
1870
+ };
1871
+ "name": {
1872
+ "alias": "name";
1873
+ "required": false;
1874
+ "isSignal": true;
1875
+ };
1876
+ "id": {
1877
+ "alias": "id";
1878
+ "required": false;
1879
+ "isSignal": true;
1880
+ };
1881
+ }, {
1882
+ "checked": "checkedChange";
1883
+ "changed": "changed";
1884
+ "touch": "touch";
1885
+ }, never, ["*"], true, never>;
1886
+ }
1887
+ /**
1888
+ * How a `bf-radio-group` lays out its options: stacked (`vertical`) or in a row (`horizontal`).
1889
+ *
1890
+ * @summary Whether a radio group stacks its options or sets them in a row
1891
+ * @since 0.3.0
1892
+ */
1893
+ type BfRadioGroupOrientation = 'vertical' | 'horizontal';
1894
+ /**
1895
+ * One choice of `bf-radio-group`; `value` is any type (a string by default).
1896
+ *
1897
+ * @summary One choice of a radio group with its value, label and optional description
1898
+ * @since 0.1.0
1899
+ */
1900
+ interface BfRadioOption<T = string> {
1901
+ /** The value the group's `value` takes when this option is chosen. */
1902
+ value: T;
1903
+ /** The visible label, also the radio's accessible name. */
1904
+ label: string;
1905
+ /** A second line under the label, linked to the radio with `aria-describedby`. */
1906
+ description?: string;
1907
+ /** Whether this option cannot be chosen. */
1908
+ disabled?: boolean;
1909
+ }
1910
+ /**
1911
+ * A group of radio buttons for choosing one of a few options, with an optional description per
1912
+ * option. Implements the Signal Forms value contract; generic over the option value (a string by
1913
+ * default), `null` while nothing is selected.
1914
+ *
1915
+ * @example
1916
+ * <bf-radio-group label="View" [options]="views" [(value)]="view" />
1917
+ * @summary Group of radio buttons for choosing one option, with optional per-option descriptions
1918
+ * @category Forms
1919
+ * @since 0.1.0
1920
+ */
1921
+ export declare class BfRadioGroupComponent<T = string> implements FormValueControl<T | null> {
1922
+ /** The selected option's value, `null` while nothing is selected; two-way bindable and bound by
1923
+ * `[formField]`. */
1924
+ readonly value: import("@angular/core").ModelSignal<T | null>;
1925
+ /** The options to choose from. */
1926
+ readonly options: import("@angular/core").InputSignal<readonly BfRadioOption<T>[]>;
1927
+ /** Equality for matching `value` to an option (default `Object.is`); pass one for object values. */
1928
+ readonly compareWith: import("@angular/core").InputSignal<BfCompareWith<T>>;
1929
+ /** Group label, rendered as the fieldset legend. */
1930
+ readonly label: import("@angular/core").InputSignal<string>;
1931
+ /**
1932
+ * Accessible name of the group when no visible `label` is rendered. Ignored when `label` is set.
1933
+ */
1934
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
1935
+ /**
1936
+ * Id(s) of the element(s) that name the group when no visible `label` is rendered. Ignored when
1937
+ * `label` is set.
1938
+ */
1939
+ readonly ariaLabelledby: import("@angular/core").InputSignal<string>;
1940
+ /** Height step of the option row: sm 32, md 40, lg 48 px (44 px under a coarse pointer for sm and md);
1941
+ * unset follows `provideBfDefaults()` (`controlSize`, `md` by default). */
1942
+ readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
1943
+ /** Stack the options vertically (default) or in a row. */
1944
+ readonly orientation: import("@angular/core").InputSignal<BfRadioGroupOrientation>;
1945
+ /** Disables every option. */
1946
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1947
+ /**
1948
+ * Shows the choice but blocks changes; the options stay focusable and the group exposes
1949
+ * `aria-readonly`.
1950
+ */
1951
+ readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1952
+ /** Marks the group required. */
1953
+ readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1954
+ /** Field validity from Signal Forms. */
1955
+ readonly invalid: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1956
+ /** Whether the user has left the field. */
1957
+ readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1958
+ /** Validation errors from Signal Forms. */
1959
+ readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
1960
+ /** Explicit error text; takes precedence over Signal Forms errors. */
1961
+ readonly errorMessage: import("@angular/core").InputSignal<string>;
1962
+ /** Shared name of the radio inputs; generated when not set. */
1963
+ readonly name: import("@angular/core").InputSignal<string>;
1964
+ /** Group id; generated when not set. */
1965
+ readonly id: import("@angular/core").InputSignal<string>;
1966
+ /** Emitted with the newly selected value after a user change (never `null`). */
1967
+ readonly changed: import("@angular/core").OutputEmitterRef<T>;
1968
+ /** Emitted on blur so Signal Forms marks the field touched. */
1969
+ readonly touch: import("@angular/core").OutputEmitterRef<void>;
1970
+ /** The rendered radio inputs, in option order; used by `focus()`. */
1971
+ private readonly radios;
1972
+ private readonly labels;
1973
+ private readonly defaults;
1974
+ /** Index of the option matching `value`, `-1` while nothing (or `null`) is selected. */
1975
+ readonly selectedIndex: import("@angular/core").Signal<number>;
1976
+ /** The size in effect: `size`, else the app's `controlSize` default. */
1977
+ protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
1978
+ readonly textClasses: import("@angular/core").Signal<string>;
1979
+ readonly errorText: import("@angular/core").Signal<string>;
1980
+ readonly showError: import("@angular/core").Signal<boolean>;
1981
+ /** The error paragraph: `errorText`, visually hidden while a press elsewhere (that blurred
1982
+ * this control) holds the layout, so it never moves under the pointer. */
1983
+ protected readonly message: HeldMessage;
1984
+ /** The id of the error paragraph (`aria-describedby`) while there is an error, else null; the
1985
+ * paragraph renders whenever it is named. */
1986
+ protected readonly errorId: import("@angular/core").Signal<string | null>;
1987
+ /**
1988
+ * `aria-label` value: only when there is no visible label, so the legend stays the sole
1989
+ * accessible name.
1990
+ */
1991
+ readonly ariaLabelAttr: import("@angular/core").Signal<string | null>;
1992
+ /** `aria-labelledby` value, under the same rule as `ariaLabelAttr`. */
1993
+ readonly ariaLabelledbyAttr: import("@angular/core").Signal<string | null>;
1994
+ readonly optionsClasses: import("@angular/core").Signal<"flex flex-row flex-wrap gap-x-6 gap-y-2" | "flex flex-col items-start gap-1">;
1995
+ protected optionLabelClasses(option: BfRadioOption<T>): string;
1996
+ protected ringClasses(option: BfRadioOption<T>, index: number): string;
1997
+ protected dotClasses(index: number): string;
1998
+ /**
1999
+ * Focuses the checked radio, else the first enabled one; Signal Forms calls it from
2000
+ * `focusBoundControl()`.
2001
+ * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.
2002
+ */
2003
+ focus(options?: FocusOptions): void;
2004
+ /**
2005
+ * Read-only: cancels the selection. Space activates a radio through a click, so this covers it.
2006
+ * @internal
2007
+ */
2008
+ onClick(event: MouseEvent): void;
2009
+ /**
2010
+ * Read-only: arrow keys would move the native selection, so they do nothing.
2011
+ * @internal
2012
+ */
2013
+ onKeydown(event: KeyboardEvent): void;
2014
+ /** Native `value` of a radio: its option's value for a primitive, its index for an object. */
2015
+ protected readonly key: typeof choiceKey;
2016
+ /**
2017
+ * Writes the value of the option at `index` to the model and emits `changed`.
2018
+ * @internal
2019
+ */
2020
+ onChange(index: number): void;
2021
+ private optionMode;
2022
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfRadioGroupComponent<any>, never>;
2023
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfRadioGroupComponent<any>, "bf-radio-group", never, {
2024
+ "value": {
2025
+ "alias": "value";
2026
+ "required": false;
2027
+ "isSignal": true;
2028
+ };
2029
+ "options": {
2030
+ "alias": "options";
2031
+ "required": true;
2032
+ "isSignal": true;
2033
+ };
2034
+ "compareWith": {
2035
+ "alias": "compareWith";
2036
+ "required": false;
2037
+ "isSignal": true;
2038
+ };
2039
+ "label": {
2040
+ "alias": "label";
2041
+ "required": false;
2042
+ "isSignal": true;
2043
+ };
2044
+ "ariaLabel": {
2045
+ "alias": "ariaLabel";
2046
+ "required": false;
2047
+ "isSignal": true;
2048
+ };
2049
+ "ariaLabelledby": {
2050
+ "alias": "ariaLabelledby";
2051
+ "required": false;
2052
+ "isSignal": true;
2053
+ };
2054
+ "size": {
2055
+ "alias": "size";
2056
+ "required": false;
2057
+ "isSignal": true;
2058
+ };
2059
+ "orientation": {
2060
+ "alias": "orientation";
2061
+ "required": false;
2062
+ "isSignal": true;
2063
+ };
2064
+ "disabled": {
2065
+ "alias": "disabled";
2066
+ "required": false;
2067
+ "isSignal": true;
2068
+ };
2069
+ "readonly": {
2070
+ "alias": "readonly";
2071
+ "required": false;
2072
+ "isSignal": true;
2073
+ };
2074
+ "required": {
2075
+ "alias": "required";
2076
+ "required": false;
2077
+ "isSignal": true;
2078
+ };
2079
+ "invalid": {
2080
+ "alias": "invalid";
2081
+ "required": false;
2082
+ "isSignal": true;
2083
+ };
2084
+ "touched": {
2085
+ "alias": "touched";
2086
+ "required": false;
2087
+ "isSignal": true;
2088
+ };
2089
+ "errors": {
2090
+ "alias": "errors";
2091
+ "required": false;
2092
+ "isSignal": true;
2093
+ };
2094
+ "errorMessage": {
2095
+ "alias": "errorMessage";
2096
+ "required": false;
2097
+ "isSignal": true;
2098
+ };
2099
+ "name": {
2100
+ "alias": "name";
2101
+ "required": false;
2102
+ "isSignal": true;
2103
+ };
2104
+ "id": {
2105
+ "alias": "id";
2106
+ "required": false;
2107
+ "isSignal": true;
2108
+ };
2109
+ }, {
2110
+ "value": "valueChange";
2111
+ "changed": "changed";
2112
+ "touch": "touch";
2113
+ }, never, never, true, never>;
2114
+ }
2115
+ /** A chip as its group sees it. */
2116
+ interface BfChipGroupItem {
2117
+ /** The value the chip stands for, compared with `Object.is`. */
2118
+ readonly value: Signal<unknown>;
2119
+ /** The chip's own `disabled` input. */
2120
+ readonly disabled: Signal<boolean>;
2121
+ /** Focuses the chip's button. */
2122
+ focus(options?: FocusOptions): void;
2123
+ }
2124
+ /** The enclosing `bf-chip-group`, as its chips inject it. */
2125
+ interface BfChipGroupHost {
2126
+ /** True in `single` mode: the chips are radios and the group owns the selection. */
2127
+ readonly radio: Signal<boolean>;
2128
+ /** Disables every chip of the group. */
2129
+ readonly disabled: Signal<boolean>;
2130
+ /** Single mode: whether `item` is the selected chip. */
2131
+ isSelected(item: BfChipGroupItem): boolean;
2132
+ /** Single mode: whether `item` owns the roving tab stop. */
2133
+ isTabStop(item: BfChipGroupItem): boolean;
2134
+ /** Single mode: selects `item`, as a click on it does. */
2135
+ select(item: BfChipGroupItem): void;
2136
+ }
2137
+ declare const BF_CHIP_GROUP: InjectionToken<BfChipGroupHost>;
2138
+ /**
2139
+ * The colour of a `bf-chip`: tonal or ink.
2140
+ *
2141
+ * @summary The two chip colours, a soft tonal tint or a dark ink fill
2142
+ * @since 0.1.0
2143
+ */
2144
+ type BfChipVariant = 'tonal' | 'ink';
2145
+ /**
2146
+ * Toggleable filter chip. Selected chips carry a check mark and a tint (`tonal`) or the ink
2147
+ * treatment used by mobile filter rows (`ink`). For a single-choice row, put the chips in a
2148
+ * `bf-chip-group`, which makes them a radio group.
2149
+ *
2150
+ * @example
2151
+ * <bf-chip [(selected)]="filters.design">Design</bf-chip>
2152
+ * <bf-chip variant="ink" [selected]="view() === 'open'" (changed)="setView('open')">Open</bf-chip>
2153
+ * @summary Toggleable filter chip with a check mark when selected, in tonal or ink style
2154
+ * @category Forms
2155
+ * @since 0.1.0
2156
+ * @slot icon-start An icon before the label.
2157
+ * @slot default Rich label content, before the `label` text.
2158
+ */
2159
+ export declare class BfChipComponent implements BfChipGroupItem {
2160
+ /** Whether the chip is selected; two-way bindable. Inside a `single`-mode `bf-chip-group` the
2161
+ * group's `value` decides and this is ignored. */
2162
+ readonly selected: import("@angular/core").ModelSignal<boolean>;
2163
+ /** The value this chip stands for inside a `bf-chip-group` (compared with `Object.is`); unused
2164
+ * outside one. */
2165
+ readonly value: import("@angular/core").InputSignal<unknown>;
2166
+ /** Selected treatment: tonal tint (default) or ink. */
2167
+ readonly variant: import("@angular/core").InputSignal<BfChipVariant>;
2168
+ /** Disables the chip. */
2169
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2170
+ /** Label text; the default slot works too. */
2171
+ readonly label: import("@angular/core").InputSignal<string>;
2172
+ /** Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`controlSize`, `md`
2173
+ * by default). */
2174
+ readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
2175
+ /** When false, clicking an already selected chip does nothing (single-choice rows). */
2176
+ readonly deselectable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2177
+ /** Emitted with the new state after a user toggle. */
2178
+ readonly changed: import("@angular/core").OutputEmitterRef<boolean>;
2179
+ /**
2180
+ * Emitted with the new state after a user toggle, together with `changed`.
2181
+ * @deprecated 0.3.0 use changed; removed in 0.4.0
2182
+ */
2183
+ readonly toggled: import("@angular/core").OutputEmitterRef<boolean>;
2184
+ readonly markClasses = "inline-block before:block before:h-[10px] before:w-[5px] before:-translate-y-px before:rotate-45 before:border-r-2 before:border-b-2 before:border-current before:content-['']";
2185
+ private readonly defaults;
2186
+ private readonly group;
2187
+ private readonly button;
2188
+ private readonly host;
2189
+ /** The size in effect: `size`, else the app's `controlSize` default. */
2190
+ protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
2191
+ /** Inside a `single`-mode group: a radio whose selection the group owns. */
2192
+ protected readonly radio: import("@angular/core").Signal<boolean>;
2193
+ /** Disabled by its own input or by its group. */
2194
+ protected readonly isDisabled: import("@angular/core").Signal<boolean>;
2195
+ /** The selection shown: the group's in a single-mode group, else `selected`. */
2196
+ protected readonly isSelected: import("@angular/core").Signal<boolean>;
2197
+ /** Roving tab stop in a single-mode group; the native order otherwise. */
2198
+ protected readonly tabIndex: import("@angular/core").Signal<0 | -1 | null>;
2199
+ readonly classes: import("@angular/core").Signal<string>;
2200
+ /**
2201
+ * Focuses the chip's button.
2202
+ * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.
2203
+ */
2204
+ focus(options?: FocusOptions): void;
2205
+ /**
2206
+ * Whether `node` is this chip or inside it; the group finds the focused chip with it.
2207
+ * @internal
2208
+ */
2209
+ contains(node: Node | null): boolean;
2210
+ /**
2211
+ * Toggles `selected` and emits `changed`, unless disabled or selected and not `deselectable`;
2212
+ * in a single-mode group, selects this chip through the group instead.
2213
+ * @internal
2214
+ */
2215
+ onClick(): void;
2216
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfChipComponent, never>;
2217
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfChipComponent, "bf-chip", never, {
2218
+ "selected": {
2219
+ "alias": "selected";
2220
+ "required": false;
2221
+ "isSignal": true;
2222
+ };
2223
+ "value": {
2224
+ "alias": "value";
2225
+ "required": false;
2226
+ "isSignal": true;
2227
+ };
2228
+ "variant": {
2229
+ "alias": "variant";
2230
+ "required": false;
2231
+ "isSignal": true;
2232
+ };
2233
+ "disabled": {
2234
+ "alias": "disabled";
2235
+ "required": false;
2236
+ "isSignal": true;
2237
+ };
2238
+ "label": {
2239
+ "alias": "label";
2240
+ "required": false;
2241
+ "isSignal": true;
2242
+ };
2243
+ "size": {
2244
+ "alias": "size";
2245
+ "required": false;
2246
+ "isSignal": true;
2247
+ };
2248
+ "deselectable": {
2249
+ "alias": "deselectable";
2250
+ "required": false;
2251
+ "isSignal": true;
2252
+ };
2253
+ }, {
2254
+ "selected": "selectedChange";
2255
+ "changed": "changed";
2256
+ "toggled": "toggled";
2257
+ }, never, ["[bfSlot=icon-start]", "*"], true, never>;
2258
+ }
2259
+ /**
2260
+ * How a `bf-chip-group` treats its chips: one selected at a time (`single`, a radio group) or
2261
+ * independent toggles (`multiple`).
2262
+ *
2263
+ * @summary Whether a chip group picks exactly one chip or lets each chip toggle alone
2264
+ * @since 0.3.0
2265
+ */
2266
+ type BfChipGroupMode = 'single' | 'multiple';
2267
+ /**
2268
+ * A named row of `bf-chip`s. In `single` mode (the default) the chips are a radio group: the
2269
+ * group owns the selected chip's `value`, one chip is the tab stop and the arrow keys move the
2270
+ * selection. In `multiple` mode the chips stay independent toggles and the group only names them.
2271
+ * Not a Signal Forms control: for a form field use `bf-segmented` or `bf-radio-group`.
2272
+ *
2273
+ * @example
2274
+ * <bf-chip-group label="Status" [(value)]="status">
2275
+ * <bf-chip value="all">All</bf-chip>
2276
+ * <bf-chip value="open">Open</bf-chip>
2277
+ * <bf-chip value="done">Done</bf-chip>
2278
+ * </bf-chip-group>
2279
+ * @summary Named row of chips that picks one like radios, or groups independent toggles
2280
+ * @category Forms
2281
+ * @since 0.3.0
2282
+ * @slot default The `bf-chip`s of the group, each with its `value`.
2283
+ */
2284
+ export declare class BfChipGroupComponent<T = string> implements BfChipGroupHost {
2285
+ /** `single` (default): one chip selected, radio semantics; `multiple`: independent toggles. */
2286
+ readonly mode: import("@angular/core").InputSignal<BfChipGroupMode>;
2287
+ /** Accessible name of the group (required unless `ariaLabelledby` is set). */
2288
+ readonly label: import("@angular/core").InputSignal<string>;
2289
+ /** Id(s) of the element(s) that name the group (e.g. a visible heading) when `label` is not set. */
2290
+ readonly ariaLabelledby: import("@angular/core").InputSignal<string>;
2291
+ /** single: the selected chip's value (`null` = none); ignored in multiple mode. Two-way. Every
2292
+ * chip of a single-mode group needs a `value` (of type `T`); one without it cannot be selected. */
2293
+ readonly value: import("@angular/core").ModelSignal<T | null>;
2294
+ /** Disables every chip of the group. */
2295
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2296
+ /** Emitted with the new value after a user change (single mode). */
2297
+ readonly changed: import("@angular/core").OutputEmitterRef<T | null>;
2298
+ /** The chips of the group, in document order. */
2299
+ private readonly chips;
2300
+ /**
2301
+ * True in `single` mode.
2302
+ * @internal
2303
+ */
2304
+ readonly radio: import("@angular/core").Signal<boolean>;
2305
+ /** The enabled chips, in order. */
2306
+ private readonly enabled;
2307
+ /** The chip matching `value`, else none. A chip without a `value` never matches, so chips
2308
+ * that all left it `undefined` cannot all read as selected. */
2309
+ private readonly selectedChip;
2310
+ /** The chip that owns the roving tab stop: the selected enabled chip, else the first enabled. */
2311
+ private readonly tabStop;
2312
+ /**
2313
+ * Whether `item` is the selected chip.
2314
+ * @internal
2315
+ */
2316
+ isSelected(item: BfChipGroupItem): boolean;
2317
+ /**
2318
+ * Whether `item` owns the roving tab stop.
2319
+ * @internal
2320
+ */
2321
+ isTabStop(item: BfChipGroupItem): boolean;
2322
+ /**
2323
+ * Selects `item` and emits `changed`, unless it is disabled, already selected or has no
2324
+ * `value` (every chip of a single-mode group needs one).
2325
+ * @internal
2326
+ */
2327
+ select(item: BfChipGroupItem): void;
2328
+ /**
2329
+ * Single mode: the arrow keys, Home and End move focus and the selection, wrapping and skipping
2330
+ * disabled chips.
2331
+ * @internal
2332
+ */
2333
+ onKeydown(event: KeyboardEvent): void;
2334
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfChipGroupComponent<any>, never>;
2335
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfChipGroupComponent<any>, "bf-chip-group", never, {
2336
+ "mode": {
2337
+ "alias": "mode";
2338
+ "required": false;
2339
+ "isSignal": true;
2340
+ };
2341
+ "label": {
2342
+ "alias": "label";
2343
+ "required": false;
2344
+ "isSignal": true;
2345
+ };
2346
+ "ariaLabelledby": {
2347
+ "alias": "ariaLabelledby";
2348
+ "required": false;
2349
+ "isSignal": true;
2350
+ };
2351
+ "value": {
2352
+ "alias": "value";
2353
+ "required": false;
2354
+ "isSignal": true;
2355
+ };
2356
+ "disabled": {
2357
+ "alias": "disabled";
2358
+ "required": false;
2359
+ "isSignal": true;
2360
+ };
2361
+ }, {
2362
+ "value": "valueChange";
2363
+ "changed": "changed";
2364
+ }, ["chips"], ["*"], true, never>;
2365
+ }
2366
+ /**
2367
+ * One segment of `bf-segmented`; `value` is any type (a string by default).
2368
+ *
2369
+ * @summary One segment of a segmented control with its value, its label and a disabled flag
2370
+ * @since 0.1.0
2371
+ */
2372
+ interface BfSegmentOption<T = string> {
2373
+ /** The value the control's `value` takes when this segment is selected. */
2374
+ value: T;
2375
+ /** The segment's visible label, also its accessible name. */
2376
+ label: string;
2377
+ /** Whether this segment cannot be selected. */
2378
+ disabled?: boolean;
2379
+ }
2380
+ /**
2381
+ * The height step of a `bf-segmented`; the same scale as every sized widget.
2382
+ *
2383
+ * @deprecated 0.3.0 use BfSize; removed in 1.0.0
2384
+ * @summary Former name of the shared size scale for segmented controls, kept until 1.0.0
2385
+ * @since 0.1.0
2386
+ */
2387
+ type BfSegmentedSize = BfSize;
2388
+ /**
2389
+ * Segmented control for switching between two to four views. Behaves like a radio group for
2390
+ * keyboard and assistive tech; implements the Signal Forms value contract. Generic over the option
2391
+ * value (a string by default), `null` while nothing is selected.
2392
+ *
2393
+ * @example
2394
+ * <bf-segmented label="Range" [options]="ranges" [(value)]="range" />
2395
+ * @summary Segmented control for switching between two to four views, keyboard-navigable like radios
2396
+ * @category Forms
2397
+ * @since 0.1.0
2398
+ */
2399
+ export declare class BfSegmentedComponent<T = string> implements FormValueControl<T | null> {
2400
+ /** The selected option's value, `null` while nothing is selected; two-way bindable and bound by
2401
+ * `[formField]`. */
2402
+ readonly value: import("@angular/core").ModelSignal<T | null>;
2403
+ /** The segments. */
2404
+ readonly options: import("@angular/core").InputSignal<readonly BfSegmentOption<T>[]>;
2405
+ /** Equality for matching `value` to an option (default `Object.is`); pass one for object values. */
2406
+ readonly compareWith: import("@angular/core").InputSignal<BfCompareWith<T>>;
2407
+ /** Height step of the control (track): sm 32, md 40, lg 48 px; unset follows
2408
+ * `provideBfDefaults()` (`controlSize`, `md` by default). */
2409
+ readonly size: import("@angular/core").InputSignal<BfSize | undefined>;
2410
+ /** Stretch the control and share the width between segments. */
2411
+ readonly fullWidth: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2412
+ /** Disables every segment. */
2413
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2414
+ /**
2415
+ * Shows the choice but blocks changes; the tab stop stays focusable and the group exposes
2416
+ * `aria-readonly`.
2417
+ */
2418
+ readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2419
+ /** Marks the choice required (`aria-required` on the group). */
2420
+ readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2421
+ /** Field validity from Signal Forms. */
2422
+ readonly invalid: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2423
+ /** Whether the user has left the field; errors show only once touched. */
2424
+ readonly touched: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2425
+ /** Validation errors from Signal Forms; the first message is shown once touched. */
2426
+ readonly errors: import("@angular/core").InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
2427
+ /** Explicit error text; takes precedence over Signal Forms errors. */
2428
+ readonly errorMessage: import("@angular/core").InputSignal<string>;
2429
+ /** Accessible name of the group (not rendered visibly). */
2430
+ readonly label: import("@angular/core").InputSignal<string>;
2431
+ /** Accessible name when `label` is not set. */
2432
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
2433
+ /**
2434
+ * Id(s) of the element(s) that name the group (e.g. a visible heading) when `label` is not set.
2435
+ */
2436
+ readonly ariaLabelledby: import("@angular/core").InputSignal<string>;
2437
+ /**
2438
+ * Name of the bound field. Not rendered, because the control has no native form element; kept so
2439
+ * Signal Forms can bind it.
2440
+ */
2441
+ readonly name: import("@angular/core").InputSignal<string>;
2442
+ /** Group id; generated when not set. */
2443
+ readonly id: import("@angular/core").InputSignal<string>;
2444
+ /** Emitted with the newly selected value after a user change (never `null`). */
2445
+ readonly changed: import("@angular/core").OutputEmitterRef<T>;
2446
+ /** Emitted on blur so Signal Forms marks the field touched. */
2447
+ readonly touch: import("@angular/core").OutputEmitterRef<void>;
2448
+ /** The rendered radio buttons, in option order; used to move focus after keyboard selection. */
2449
+ readonly radios: import("@angular/core").Signal<readonly ElementRef<HTMLButtonElement>[]>;
2450
+ /** Index of the option matching `value`, `-1` while nothing (or `null`) is selected. */
2451
+ readonly selectedIndex: import("@angular/core").Signal<number>;
2452
+ /** Index of the option that owns the roving tab stop: the selected enabled option, or the first
2453
+ * enabled option when nothing valid is selected; `-1` when every option is disabled. */
2454
+ readonly tabStop: import("@angular/core").Signal<number>;
2455
+ private readonly labels;
2456
+ private readonly defaults;
2457
+ /** The size in effect: `size`, else the app's `controlSize` default. */
2458
+ protected readonly resolvedSize: import("@angular/core").Signal<BfSize>;
2459
+ readonly errorText: import("@angular/core").Signal<string>;
2460
+ readonly showError: import("@angular/core").Signal<boolean>;
2461
+ /** The error paragraph: `errorText`, visually hidden while a press elsewhere (that blurred
2462
+ * this control) holds the layout, so it never moves under the pointer. */
2463
+ protected readonly message: HeldMessage;
2464
+ /** The id of the error paragraph (`aria-describedby`) while there is an error, else null; the
2465
+ * paragraph renders whenever it is named. */
2466
+ protected readonly errorId: import("@angular/core").Signal<string | null>;
2467
+ /** `aria-label`: the `label`, else `ariaLabel`. */
2468
+ readonly ariaLabelAttr: import("@angular/core").Signal<string | null>;
2469
+ /** `aria-labelledby`: only while no `label` names the group. */
2470
+ readonly ariaLabelledbyAttr: import("@angular/core").Signal<string | null>;
2471
+ private readonly mode;
2472
+ /** The classes of the scroller around the track. */
2473
+ protected readonly scrollerClasses: import("@angular/core").Signal<string>;
2474
+ readonly trackClasses: import("@angular/core").Signal<string>;
2475
+ /**
2476
+ * The classes of the segment at `index`.
2477
+ * @internal
2478
+ */
2479
+ itemClasses(index: number): string;
2480
+ /**
2481
+ * Focuses the segment that owns the tab stop; Signal Forms calls it from `focusBoundControl()`.
2482
+ * @param options Passed on to the native `focus()`, such as `{ preventScroll: true }`.
2483
+ */
2484
+ focus(options?: FocusOptions): void;
2485
+ /**
2486
+ * Selects the option whose value matches `next` under `compareWith`, as a click would.
2487
+ * @param next The value of the option to select.
2488
+ */
2489
+ select(next: T): void;
2490
+ /**
2491
+ * Selects the option at `index` unless the control is disabled or read-only, the option is
2492
+ * missing, or it is already selected.
2493
+ * @param index The position of the option in `options`.
2494
+ */
2495
+ selectAt(index: number): void;
2496
+ /**
2497
+ * Arrow keys, Home and End move the selection, as in a radio group.
2498
+ * @internal
2499
+ */
2500
+ onKeydown(event: KeyboardEvent): void;
2501
+ private focusRadio;
2502
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfSegmentedComponent<any>, never>;
2503
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfSegmentedComponent<any>, "bf-segmented", never, {
2504
+ "value": {
2505
+ "alias": "value";
2506
+ "required": false;
2507
+ "isSignal": true;
2508
+ };
2509
+ "options": {
2510
+ "alias": "options";
2511
+ "required": true;
2512
+ "isSignal": true;
2513
+ };
2514
+ "compareWith": {
2515
+ "alias": "compareWith";
2516
+ "required": false;
2517
+ "isSignal": true;
2518
+ };
2519
+ "size": {
2520
+ "alias": "size";
2521
+ "required": false;
2522
+ "isSignal": true;
2523
+ };
2524
+ "fullWidth": {
2525
+ "alias": "fullWidth";
2526
+ "required": false;
2527
+ "isSignal": true;
2528
+ };
2529
+ "disabled": {
2530
+ "alias": "disabled";
2531
+ "required": false;
2532
+ "isSignal": true;
2533
+ };
2534
+ "readonly": {
2535
+ "alias": "readonly";
2536
+ "required": false;
2537
+ "isSignal": true;
2538
+ };
2539
+ "required": {
2540
+ "alias": "required";
2541
+ "required": false;
2542
+ "isSignal": true;
2543
+ };
2544
+ "invalid": {
2545
+ "alias": "invalid";
2546
+ "required": false;
2547
+ "isSignal": true;
2548
+ };
2549
+ "touched": {
2550
+ "alias": "touched";
2551
+ "required": false;
2552
+ "isSignal": true;
2553
+ };
2554
+ "errors": {
2555
+ "alias": "errors";
2556
+ "required": false;
2557
+ "isSignal": true;
2558
+ };
2559
+ "errorMessage": {
2560
+ "alias": "errorMessage";
2561
+ "required": false;
2562
+ "isSignal": true;
2563
+ };
2564
+ "label": {
2565
+ "alias": "label";
2566
+ "required": false;
2567
+ "isSignal": true;
2568
+ };
2569
+ "ariaLabel": {
2570
+ "alias": "ariaLabel";
2571
+ "required": false;
2572
+ "isSignal": true;
2573
+ };
2574
+ "ariaLabelledby": {
2575
+ "alias": "ariaLabelledby";
2576
+ "required": false;
2577
+ "isSignal": true;
2578
+ };
2579
+ "name": {
2580
+ "alias": "name";
2581
+ "required": false;
2582
+ "isSignal": true;
2583
+ };
2584
+ "id": {
2585
+ "alias": "id";
2586
+ "required": false;
2587
+ "isSignal": true;
2588
+ };
2589
+ }, {
2590
+ "value": "valueChange";
2591
+ "changed": "changed";
2592
+ "touch": "touch";
2593
+ }, never, never, true, never>;
2594
+ }
2595
+ /**
2596
+ * Container for `bf-list-item` rows. The inset style (default) wraps the rows in the warm
2597
+ * background with rounded corners, as in the design's grouped lists.
2598
+ *
2599
+ * @example
2600
+ * <bf-list>
2601
+ * <bf-list-item title="Notifications" subtitle="Every Monday at 8:00" />
2602
+ * </bf-list>
2603
+ * @summary Container for list rows, inset by default with rounded corners on a warm background
2604
+ * @category Data display
2605
+ * @since 0.1.0
2606
+ * @slot default The rows, each a `bf-list-item`.
2607
+ */
2608
+ export declare class BfListComponent {
2609
+ /** Grouped look with the warm container; false renders rows on the page background. */
2610
+ readonly inset: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2611
+ readonly classes: import("@angular/core").Signal<"flex flex-col gap-1 rounded-card bg-bg p-1.5" | "flex flex-col gap-2 bg-transparent p-0">;
2612
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfListComponent, never>;
2613
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfListComponent, "bf-list", never, {
2614
+ "inset": {
2615
+ "alias": "inset";
2616
+ "required": false;
2617
+ "isSignal": true;
2618
+ };
2619
+ }, {}, never, ["*"], true, never>;
2620
+ }
2621
+ /**
2622
+ * Provided by the surfaces a `bfAction` stretches over (`bf-card`, `bf-list-item`), so the nearest
2623
+ * one, and only it, shows the clickable cues: a card holding navigation rows is not lit by the
2624
+ * rows' links. Kept in its own file so the directive and the surfaces never import each other.
2625
+ */
2626
+ interface BfActionHost {
2627
+ /** Called by a `bfAction` inside the surface; returns its unregister function. */
2628
+ registerAction(): () => void;
2629
+ /** Whether the surface's action has keyboard focus (`:focus-visible`), for the focus ring. */
2630
+ setActionFocusVisible(visible: boolean): void;
2631
+ }
2632
+ declare const BF_ACTION_HOST: InjectionToken<BfActionHost>;
2633
+ /**
2634
+ * One row of a list: leading slot (avatar, icon tile), title and subtitle, trailing slot
2635
+ * (time, toggle, badge) and an optional chevron for rows that navigate. A navigation row puts a
2636
+ * `bfAction` link in the `title` slot, so the row stays a list item and the link covers it.
2637
+ *
2638
+ * @example
2639
+ * <bf-list-item subtitle="lena@studio.ch" chevron>
2640
+ * <bf-avatar bfSlot="leading" initials="LM" />
2641
+ * <a bfSlot="title" bfAction routerLink="/account">Account</a>
2642
+ * </bf-list-item>
2643
+ * @summary List row with leading slot, title, subtitle, trailing slot and an optional chevron
2644
+ * @category Data display
2645
+ * @since 0.1.0
2646
+ * @slot leading Content before the text, such as an avatar or an icon.
2647
+ * @slot title Rich title content, instead of or next to the `title` text.
2648
+ * @slot default More content under the title and subtitle.
2649
+ * @slot trailing Content at the end, such as a toggle, a badge or a button.
2650
+ */
2651
+ export declare class BfListItemComponent implements BfActionHost {
2652
+ /** Primary text. For a navigation row, project an `<a bfSlot="title" bfAction>` instead. */
2653
+ readonly title: import("@angular/core").InputSignal<string>;
2654
+ /** Secondary text under the title. */
2655
+ readonly subtitle: import("@angular/core").InputSignal<string>;
2656
+ /** Render the row as a button that emits `clicked` (an action row; a row that navigates puts a
2657
+ * `bfAction` link in the `title` slot instead). */
2658
+ readonly interactive: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2659
+ /** Show a trailing chevron (navigation rows). */
2660
+ readonly chevron: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2661
+ /** Disable an interactive row. */
2662
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2663
+ /**
2664
+ * Keep the title, the title slot and the subtitle on one line each, cut with an ellipsis. By
2665
+ * default they wrap, so nothing is lost at large text sizes.
2666
+ */
2667
+ readonly truncate: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2668
+ /** Emitted when an interactive row is activated. */
2669
+ readonly clicked: import("@angular/core").OutputEmitterRef<Event>;
2670
+ /** `listitem` inside a `bf-list`, else no role. */
2671
+ protected readonly role: string | null;
2672
+ private readonly actions;
2673
+ private readonly actionFocusVisible;
2674
+ private readonly actionState;
2675
+ /** Wrap or truncate classes of the title, the title slot and the subtitle. */
2676
+ protected readonly textClasses: import("@angular/core").Signal<string>;
2677
+ readonly classes: import("@angular/core").Signal<string>;
2678
+ /** @internal Called by a `bfAction` in the row. */
2679
+ registerAction(): () => void;
2680
+ /** @internal Called by the row's `bfAction` on focus and blur. */
2681
+ setActionFocusVisible(visible: boolean): void;
2682
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfListItemComponent, never>;
2683
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfListItemComponent, "bf-list-item", never, {
2684
+ "title": {
2685
+ "alias": "title";
2686
+ "required": false;
2687
+ "isSignal": true;
2688
+ };
2689
+ "subtitle": {
2690
+ "alias": "subtitle";
2691
+ "required": false;
2692
+ "isSignal": true;
2693
+ };
2694
+ "interactive": {
2695
+ "alias": "interactive";
2696
+ "required": false;
2697
+ "isSignal": true;
2698
+ };
2699
+ "chevron": {
2700
+ "alias": "chevron";
2701
+ "required": false;
2702
+ "isSignal": true;
2703
+ };
2704
+ "disabled": {
2705
+ "alias": "disabled";
2706
+ "required": false;
2707
+ "isSignal": true;
2708
+ };
2709
+ "truncate": {
2710
+ "alias": "truncate";
2711
+ "required": false;
2712
+ "isSignal": true;
2713
+ };
2714
+ }, {
2715
+ "clicked": "clicked";
2716
+ }, never, ["[bfSlot=leading]", "[bfSlot=title]", "*", "[bfSlot=trailing]"], true, never>;
2717
+ }
2718
+ /**
2719
+ * The surface of a `bf-card`: raised, tint, ink or flat.
2720
+ *
2721
+ * @summary The four card surfaces, from a raised panel to a flat outline
2722
+ * @since 0.1.0
2723
+ */
2724
+ type BfCardVariant = 'raised' | 'tint' | 'ink' | 'flat';
2725
+ /**
2726
+ * The inner padding of a `bf-card`: md or lg.
2727
+ *
2728
+ * @summary The two inner paddings of a card, regular and roomy
2729
+ * @since 0.1.0
2730
+ */
2731
+ type BfCardPadding = 'md' | 'lg';
2732
+ /**
2733
+ * Surface for a piece of content: a project summary, a stat, a focus prompt. Four variants from
2734
+ * the design: raised (default), tint, ink and flat. To make the whole card clickable, put a
2735
+ * `bfAction` link or button in its heading (the stretched-link pattern).
2736
+ *
2737
+ * @example
2738
+ * <bf-card>
2739
+ * <span bfSlot="header" class="text-caption text-text-muted">Project</span>
2740
+ * <h3 class="text-heading"><a bfAction routerLink="/projects/atlas">Atlas rebrand</a></h3>
2741
+ * <bf-progress [value]="68" label="Progress" />
2742
+ * </bf-card>
2743
+ * @summary Content surface with an optional header slot, in four visual styles from raised to flat
2744
+ * @category Data display
2745
+ * @since 0.1.0
2746
+ * @slot header Content above the body, such as a title row.
2747
+ * @slot default The card body.
2748
+ * @slot footer Content below the body, such as its actions.
2749
+ */
2750
+ export declare class BfCardComponent implements BfActionHost {
2751
+ /** Surface treatment: raised (default), tint, ink, flat. */
2752
+ readonly variant: import("@angular/core").InputSignal<BfCardVariant>;
2753
+ /** Whole card is a button that emits `clicked`.
2754
+ * @deprecated 0.3.0 use a bfAction link or button in the card's heading; removed in 1.0.0 */
2755
+ readonly interactive: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2756
+ /** Inner padding: md 18 px (`--spacing-card`), lg 24 px (`--spacing-card-lg`). */
2757
+ readonly padding: import("@angular/core").InputSignal<BfCardPadding>;
2758
+ /** Emitted when an interactive card is activated.
2759
+ * @deprecated 0.3.0 use a bfAction link or button in the card's heading; removed in 1.0.0 */
2760
+ readonly clicked: import("@angular/core").OutputEmitterRef<Event>;
2761
+ private readonly actions;
2762
+ private readonly actionFocusVisible;
2763
+ readonly classes: import("@angular/core").Signal<string>;
2764
+ private readonly actionState;
2765
+ /** @internal Called by a `bfAction` in the card. */
2766
+ registerAction(): () => void;
2767
+ /** @internal Called by the card's `bfAction` on focus and blur. */
2768
+ setActionFocusVisible(visible: boolean): void;
2769
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfCardComponent, never>;
2770
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfCardComponent, "bf-card", never, {
2771
+ "variant": {
2772
+ "alias": "variant";
2773
+ "required": false;
2774
+ "isSignal": true;
2775
+ };
2776
+ "interactive": {
2777
+ "alias": "interactive";
2778
+ "required": false;
2779
+ "isSignal": true;
2780
+ };
2781
+ "padding": {
2782
+ "alias": "padding";
2783
+ "required": false;
2784
+ "isSignal": true;
2785
+ };
2786
+ }, {
2787
+ "clicked": "clicked";
2788
+ }, never, ["[bfSlot=header]", "*", "[bfSlot=footer]"], true, never>;
2789
+ }
2790
+ /**
2791
+ * The track height of a `bf-progress`: sm or md.
2792
+ *
2793
+ * @summary The two track heights of a progress bar, thin and regular
2794
+ * @since 0.1.0
2795
+ */
2796
+ type BfProgressSize = 'sm' | 'md';
2797
+ /**
2798
+ * The fill colour of a `bf-progress`: primary, success, warning or danger.
2799
+ *
2800
+ * @summary The four fill colours of a progress bar, from primary to danger
2801
+ * @since 0.1.0
2802
+ */
2803
+ type BfProgressTone = 'primary' | 'success' | 'warning' | 'danger';
2804
+ /**
2805
+ * Progress bar for completion and quotas, determinate by default, or `indeterminate` while the
2806
+ * amount of work is unknown.
2807
+ *
2808
+ * @example
2809
+ * <bf-progress [value]="68" label="Atlas rebrand" valueText="12 of 18 tasks" />
2810
+ * <bf-progress indeterminate label="Uploading" />
2811
+ * @summary Progress bar in two sizes and four tones for completion, quotas and unknown waits
2812
+ * @category Data display
2813
+ * @since 0.1.0
2814
+ */
2815
+ export declare class BfProgressComponent {
2816
+ /** Completion in percent; clamped to 0–100. Without it (and without `indeterminate`) the bar
2817
+ * shows 0 %. Ignored while `indeterminate`. */
2818
+ readonly value: import("@angular/core").InputSignal<number | undefined>;
2819
+ /** The amount of work is unknown: the native bar carries no value (assistive tech announces it
2820
+ * as busy) and a stripe runs across the track, a static 40 % bar under reduced motion. */
2821
+ readonly indeterminate: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2822
+ /** The value in words for assistive tech (`aria-valuetext`), such as "12 of 18 tasks"; the
2823
+ * percentage is announced while it is empty. */
2824
+ readonly valueText: import("@angular/core").InputSignal<string>;
2825
+ /** Accessible name of the bar ("Atlas rebrand"). */
2826
+ readonly label: import("@angular/core").InputSignal<string>;
2827
+ /** Bar height: sm 8 px (default), md 10 px. */
2828
+ readonly size: import("@angular/core").InputSignal<BfProgressSize>;
2829
+ /** Fill color by meaning. */
2830
+ readonly tone: import("@angular/core").InputSignal<BfProgressTone>;
2831
+ readonly percent: import("@angular/core").Signal<number>;
2832
+ readonly classes: import("@angular/core").Signal<string>;
2833
+ readonly stripeClasses: import("@angular/core").Signal<string>;
2834
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfProgressComponent, never>;
2835
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfProgressComponent, "bf-progress", never, {
2836
+ "value": {
2837
+ "alias": "value";
2838
+ "required": false;
2839
+ "isSignal": true;
2840
+ };
2841
+ "indeterminate": {
2842
+ "alias": "indeterminate";
2843
+ "required": false;
2844
+ "isSignal": true;
2845
+ };
2846
+ "valueText": {
2847
+ "alias": "valueText";
2848
+ "required": false;
2849
+ "isSignal": true;
2850
+ };
2851
+ "label": {
2852
+ "alias": "label";
2853
+ "required": true;
2854
+ "isSignal": true;
2855
+ };
2856
+ "size": {
2857
+ "alias": "size";
2858
+ "required": false;
2859
+ "isSignal": true;
2860
+ };
2861
+ "tone": {
2862
+ "alias": "tone";
2863
+ "required": false;
2864
+ "isSignal": true;
2865
+ };
2866
+ }, {}, never, never, true, never>;
2867
+ }
2868
+ /**
2869
+ * The size of a `bf-avatar`: sm, md or lg.
2870
+ *
2871
+ * @summary The three sizes of an avatar, from a list row to a profile header
2872
+ * @since 0.1.0
2873
+ */
2874
+ type BfAvatarSize = 'sm' | 'md' | 'lg';
2875
+ /**
2876
+ * The colour scheme of a `bf-avatar`: tint, ink, warning or neutral.
2877
+ *
2878
+ * @summary The four colour schemes of an avatar behind its initials or icon
2879
+ * @since 0.1.0
2880
+ */
2881
+ type BfAvatarVariant = 'tint' | 'ink' | 'warning' | 'neutral';
2882
+ /**
2883
+ * Round avatar showing a photo or initials.
2884
+ *
2885
+ * @example
2886
+ * <bf-avatar initials="LM" />
2887
+ * <bf-avatar src="/lena.jpg" alt="Lena Moser" size="lg" />
2888
+ * @summary Round avatar showing a photo or initials, in three sizes and four color variants
2889
+ * @category Data display
2890
+ * @since 0.1.0
2891
+ */
2892
+ export declare class BfAvatarComponent {
2893
+ /** One or two letters shown when there is no image. */
2894
+ readonly initials: import("@angular/core").InputSignal<string>;
2895
+ /** Image URL; when set, the image replaces the initials. */
2896
+ readonly src: import("@angular/core").InputSignal<string>;
2897
+ /** Accessible name; when unset the avatar is decorative and hidden from assistive tech. */
2898
+ readonly alt: import("@angular/core").InputSignal<string>;
2899
+ /** Diameter: sm 30 px, md 40 px (default), lg 84 px; at least 4.5ex of the initials, so a text
2900
+ * zoom (Android font scale) grows the circle with its initials. */
2901
+ readonly size: import("@angular/core").InputSignal<BfAvatarSize>;
2902
+ /** Background treatment for the initials. */
2903
+ readonly variant: import("@angular/core").InputSignal<BfAvatarVariant>;
2904
+ readonly classes: import("@angular/core").Signal<string>;
2905
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfAvatarComponent, never>;
2906
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfAvatarComponent, "bf-avatar", never, {
2907
+ "initials": {
2908
+ "alias": "initials";
2909
+ "required": false;
2910
+ "isSignal": true;
2911
+ };
2912
+ "src": {
2913
+ "alias": "src";
2914
+ "required": false;
2915
+ "isSignal": true;
2916
+ };
2917
+ "alt": {
2918
+ "alias": "alt";
2919
+ "required": false;
2920
+ "isSignal": true;
2921
+ };
2922
+ "size": {
2923
+ "alias": "size";
2924
+ "required": false;
2925
+ "isSignal": true;
2926
+ };
2927
+ "variant": {
2928
+ "alias": "variant";
2929
+ "required": false;
2930
+ "isSignal": true;
2931
+ };
2932
+ }, {}, never, never, true, never>;
2933
+ }
2934
+ /**
2935
+ * The tone of a `bf-alert`: neutral, success, warning or danger.
2936
+ *
2937
+ * @summary The four tones of an alert, from neutral information to a danger message
2938
+ * @since 0.1.0
2939
+ */
2940
+ type BfAlertVariant = 'neutral' | 'success' | 'warning' | 'danger';
2941
+ /**
2942
+ * Inline message for the outcome of an action or the state of a screen, in a polite `status`
2943
+ * region (`urgent` makes it an assertive `alert`; `announce` makes an inserted alert heard).
2944
+ *
2945
+ * @example
2946
+ * <bf-alert variant="success" title="Saved" announce>Your changes are live.</bf-alert>
2947
+ * <bf-alert variant="danger" title="Sync failed" urgent [dismissible]="true" (dismissed)="clear()">Check your connection.</bf-alert>
2948
+ * @summary Inline status message in four tones with a title and an optional dismiss button
2949
+ * @category Feedback
2950
+ * @since 0.1.0
2951
+ * @slot icon An icon before the text, such as a `bf-icon`.
2952
+ * @slot default The message, under the title.
2953
+ * @slot actions Buttons under the message, such as Retry.
2954
+ */
2955
+ export declare class BfAlertComponent {
2956
+ /** Meaning of the message. */
2957
+ readonly variant: import("@angular/core").InputSignal<BfAlertVariant>;
2958
+ /** Bold first line. */
2959
+ readonly title: import("@angular/core").InputSignal<string>;
2960
+ /** Shows a dismiss button that emits `dismissed`; the host decides whether to hide the alert. */
2961
+ readonly dismissible: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2962
+ /** `role="alert"` (assertive) instead of `status`; for errors that need attention now. */
2963
+ readonly urgent: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2964
+ /** Renders the live region empty and fills it on the next frame, so an alert inserted after an
2965
+ * action is announced; read once, when the alert is created. */
2966
+ readonly announce: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2967
+ /** Accessible name of the dismiss button (empty falls back to `provideBfLabels()`'s `dismiss`,
2968
+ * "Dismiss"); with a `title` it becomes the label, a colon and the title ("Dismiss: Saved"). */
2969
+ readonly dismissLabel: import("@angular/core").InputSignal<string>;
2970
+ /** Emitted when the dismiss button is pressed. */
2971
+ readonly dismissed: import("@angular/core").OutputEmitterRef<void>;
2972
+ private readonly labels;
2973
+ /** `announce` as it was when the alert was created; later changes are ignored. */
2974
+ private readonly deferred;
2975
+ private readonly frameReady;
2976
+ /** Whether the live region holds its content (at once, or a frame later with `announce`). */
2977
+ protected readonly filled: import("@angular/core").Signal<boolean>;
2978
+ /** The dismiss button's rendered name: `dismissLabel` (else the `dismiss` label), then the title. */
2979
+ readonly dismissName: import("@angular/core").Signal<string>;
2980
+ readonly classes: import("@angular/core").Signal<string>;
2981
+ readonly contentClasses: import("@angular/core").Signal<string>;
2982
+ constructor();
2983
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfAlertComponent, never>;
2984
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfAlertComponent, "bf-alert", never, {
2985
+ "variant": {
2986
+ "alias": "variant";
2987
+ "required": false;
2988
+ "isSignal": true;
2989
+ };
2990
+ "title": {
2991
+ "alias": "title";
2992
+ "required": false;
2993
+ "isSignal": true;
2994
+ };
2995
+ "dismissible": {
2996
+ "alias": "dismissible";
2997
+ "required": false;
2998
+ "isSignal": true;
2999
+ };
3000
+ "urgent": {
3001
+ "alias": "urgent";
3002
+ "required": false;
3003
+ "isSignal": true;
3004
+ };
3005
+ "announce": {
3006
+ "alias": "announce";
3007
+ "required": false;
3008
+ "isSignal": true;
3009
+ };
3010
+ "dismissLabel": {
3011
+ "alias": "dismissLabel";
3012
+ "required": false;
3013
+ "isSignal": true;
3014
+ };
3015
+ }, {
3016
+ "dismissed": "dismissed";
3017
+ }, never, ["[bfSlot=icon]", "*", "[bfSlot=actions]"], true, never>;
3018
+ }
3019
+ /**
3020
+ * The heading level of a `bf-empty-state` title: `2` for a screen, `3` inside a section.
3021
+ *
3022
+ * @summary The heading level of an empty state title, two for a screen or three
3023
+ * @since 0.3.0
3024
+ */
3025
+ type BfEmptyStateHeadingLevel = 2 | 3;
3026
+ /**
3027
+ * Placeholder for a screen or list with nothing in it yet: an icon tile, a title, one sentence,
3028
+ * and the action that fills it.
3029
+ *
3030
+ * @example
3031
+ * <bf-empty-state title="No tasks yet" description="Add your first task to get started.">
3032
+ * <bf-icon bfSlot="icon" [icon]="ListTodo" size="lg" />
3033
+ * <bf-button bfSlot="actions" (clicked)="create()">New task</bf-button>
3034
+ * </bf-empty-state>
3035
+ * @summary Placeholder for an empty screen or list with icon, title, message and action
3036
+ * @category Feedback
3037
+ * @since 0.1.0
3038
+ * @slot icon The icon in the tile above the title.
3039
+ * @slot actions Buttons under the description, such as Create.
3040
+ */
3041
+ export declare class BfEmptyStateComponent {
3042
+ /** What is missing, as a short title. */
3043
+ readonly title: import("@angular/core").InputSignal<string>;
3044
+ /** One sentence on how to fill it. */
3045
+ readonly description: import("@angular/core").InputSignal<string>;
3046
+ /** Heading level of the title so the empty state fits the page outline. */
3047
+ readonly headingLevel: import("@angular/core").InputSignal<BfEmptyStateHeadingLevel>;
3048
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfEmptyStateComponent, never>;
3049
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfEmptyStateComponent, "bf-empty-state", never, {
3050
+ "title": {
3051
+ "alias": "title";
3052
+ "required": true;
3053
+ "isSignal": true;
3054
+ };
3055
+ "description": {
3056
+ "alias": "description";
3057
+ "required": false;
3058
+ "isSignal": true;
3059
+ };
3060
+ "headingLevel": {
3061
+ "alias": "headingLevel";
3062
+ "required": false;
3063
+ "isSignal": true;
3064
+ };
3065
+ }, {}, never, ["[bfSlot=icon]", "[bfSlot=actions]"], true, never>;
3066
+ }
3067
+ /**
3068
+ * Floating pill of actions that appears when items are selected. Position it yourself
3069
+ * (bottom-centre, above the safe area on mobile); the bar only styles itself.
3070
+ *
3071
+ * @example
3072
+ * <div class="fixed inset-x-0 bottom-6 flex justify-center">
3073
+ * <bf-action-bar [label]="selected() + ' selected'">
3074
+ * <bf-button variant="text" size="sm" (clicked)="clear()">Clear</bf-button>
3075
+ * <bf-button size="sm" (clicked)="complete()">Mark done</bf-button>
3076
+ * </bf-action-bar>
3077
+ * </div>
3078
+ * @summary Floating pill of contextual actions that appears while items are selected
3079
+ * @category Actions
3080
+ * @since 0.1.0
3081
+ * @slot default The actions: buttons and icon buttons, laid out in the bar.
3082
+ */
3083
+ export declare class BfActionBarComponent {
3084
+ /** Leading text, e.g. "2 selected". */
3085
+ readonly label: import("@angular/core").InputSignal<string>;
3086
+ readonly labelId: string;
3087
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfActionBarComponent, never>;
3088
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfActionBarComponent, "bf-action-bar", never, {
3089
+ "label": {
3090
+ "alias": "label";
3091
+ "required": false;
3092
+ "isSignal": true;
3093
+ };
3094
+ }, {}, never, ["*"], true, never>;
3095
+ }
3096
+ /**
3097
+ * What `bf-tab` needs from its enclosing `bf-tab-bar`, provided through an injection token so
3098
+ * `tab-bar.component.ts` and `tab.component.ts` never import each other.
3099
+ *
3100
+ * @summary What each tab reads from its tab bar: the selection, tab stop and link mode
3101
+ * @since 0.1.0
3102
+ */
3103
+ interface BfTabBarHost {
3104
+ /** The id of the selected tab, the bar's `active` model. */
3105
+ readonly active: Signal<string>;
3106
+ /** The id of the tab shown as selected: `active`, or the controller's `current()` inside a
3107
+ * parent that provides `BF_TAB_BAR_CONTROLLER` (`bf-tabs`). Optional, so a custom `BF_TAB_BAR`
3108
+ * provider without it keeps working: `bf-tab` then reads `active`. */
3109
+ readonly selected?: Signal<string>;
3110
+ /** The id that currently owns the roving tab stop: the active enabled tab, or the first enabled
3111
+ * tab when nothing valid is selected. */
3112
+ readonly tabStop: Signal<string>;
3113
+ /** True when a router-aware parent provides `BF_TAB_LINKS`: the tabs render as links in a
3114
+ * `nav`, not as a `tablist`. */
3115
+ readonly linkMode: boolean;
3116
+ /**
3117
+ * The URL of tab `id` in link mode; `null` without `BF_TAB_LINKS`.
3118
+ * @param id The `id` of the tab.
3119
+ */
3120
+ linkHref(id: string): string | null;
3121
+ /**
3122
+ * Whether the current page is tab `id`'s root page (`aria-current="page"`) rather than a
3123
+ * child page of it (`aria-current="true"`); `true` without `BF_TAB_LINKS`.
3124
+ * @param id The `id` of the tab.
3125
+ */
3126
+ linkIsRoot(id: string): boolean;
3127
+ /**
3128
+ * Selects tab `id`, as a click on it would.
3129
+ * @param id The `id` of the tab.
3130
+ */
3131
+ select(id: string): void;
3132
+ }
3133
+ /**
3134
+ * The enclosing `bf-tab-bar`, as its tabs inject it.
3135
+ *
3136
+ * @summary Injection token through which each tab reaches its enclosing tab bar
3137
+ * @since 0.1.0
3138
+ */
3139
+ export declare const BF_TAB_BAR: InjectionToken<BfTabBarHost>;
3140
+ /**
3141
+ * Provided by a router-aware parent (`bf-tabs`) to render the projected bar as a `nav` of links:
3142
+ * `href(id)` is the URL of tab `id`, used for the link's `href` (open in a new tab, copy the
3143
+ * link, see the URL). A plain click still goes through `bf-tab-bar`'s `select()`.
3144
+ *
3145
+ * @summary The URLs a router-aware parent gives a tab bar to render its tabs as links
3146
+ * @since 0.3.0
3147
+ */
3148
+ interface BfTabLinks {
3149
+ /**
3150
+ * The URL of tab `id`'s root page, the link's `href`.
3151
+ * @param id The `id` of the tab.
3152
+ */
3153
+ href(id: string): string;
3154
+ /**
3155
+ * Whether the current page is tab `id`'s root page; read in a reactive context, so back it
3156
+ * with signals.
3157
+ * @param id The `id` of the tab.
3158
+ */
3159
+ isRoot(id: string): boolean;
3160
+ }
3161
+ /**
3162
+ * The link source of a tab bar in link mode, provided by `bf-tabs`.
3163
+ *
3164
+ * @summary Injection token that turns a projected tab bar into a navigation of links
3165
+ * @since 0.3.0
3166
+ */
3167
+ export declare const BF_TAB_LINKS: InjectionToken<BfTabLinks>;
3168
+ /**
3169
+ * Provided by a parent that projects the bar and drives it (bf-tabs); the bar derives its state from it.
3170
+ *
3171
+ * @summary The state a parent that drives a projected tab bar gives it to derive from
3172
+ * @since 0.3.0
3173
+ */
3174
+ interface BfTabBarController extends BfTabLinks {
3175
+ /** The tab the parent shows: the in-flight navigation's target, else the current URL's; null when unknown. */
3176
+ readonly current: Signal<string | null>;
3177
+ /** Hide the bar (e.g. while the soft keyboard is open or about to open). */
3178
+ readonly hidden: Signal<boolean>;
3179
+ /** Animate hiding (iOS) or switch instantly. */
3180
+ readonly hideTransition: Signal<boolean>;
3181
+ /**
3182
+ * Called by the bar on a user selection of another tab.
3183
+ * @param id The `id` of the selected tab.
3184
+ */
3185
+ select(id: string): void;
3186
+ /**
3187
+ * Called by the bar on a user selection of the active tab.
3188
+ * @param id The `id` of the active tab.
3189
+ */
3190
+ reselect(id: string): void;
3191
+ }
3192
+ /**
3193
+ * The controller of a tab bar projected into a parent that drives it, provided by `bf-tabs`.
3194
+ *
3195
+ * @summary Injection token through which a parent drives the selection and hiding of its tab bar
3196
+ * @since 0.3.0
3197
+ */
3198
+ export declare const BF_TAB_BAR_CONTROLLER: InjectionToken<BfTabBarController>;
3199
+ /**
3200
+ * One destination inside `bf-tab-bar`: icon in the default slot, `label` under it, optional count
3201
+ * `badge`. A `button role="tab"` in a standalone bar; inside `bf-tabs`, a link to the tab's URL
3202
+ * with `aria-current` while active: `page` on the tab's root page, `true` on a child page of it
3203
+ * (the current section, not the current page).
3204
+ *
3205
+ * @example
3206
+ * <bf-tab id="today" label="Today"><bf-icon [icon]="Sun" /></bf-tab>
3207
+ * @summary One tab bar destination with an icon, a label and an optional count badge
3208
+ * @category Navigation
3209
+ * @since 0.1.0
3210
+ * @slot default The tab icon, a `bf-icon` above the label.
3211
+ */
3212
+ export declare class BfTabComponent {
3213
+ /** Stable identifier; matches `bf-tab-bar`'s `active` when this tab is selected. It is a
3214
+ * selection key only, never reflected as the DOM `id` of more than the inner `<button>` (or
3215
+ * `<a>` inside `bf-tabs`). */
3216
+ readonly id: import("@angular/core").InputSignal<string>;
3217
+ /** Visible label under the icon. */
3218
+ readonly label: import("@angular/core").InputSignal<string>;
3219
+ /** Optional count shown as a badge on the icon capsule; announced to screen readers as part of
3220
+ * the tab's accessible name (`aria-label` "{label}, {announcement}", with `provideBfLabels()`'s
3221
+ * `tabBadge(n)`, `"{n} new"`, for a number, the string as-is otherwise) since the badge itself
3222
+ * is `aria-hidden`. */
3223
+ readonly badge: import("@angular/core").InputSignal<string | number | null>;
3224
+ /** Disables the tab: skipped by keyboard navigation, cannot be clicked. */
3225
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
3226
+ /** The enclosing `bf-tab-bar`, provided through `BF_TAB_BAR` so the two files don't import each other. */
3227
+ readonly bar: import("@bitforgehq/ui").BfTabBarHost;
3228
+ private readonly labels;
3229
+ private readonly control;
3230
+ /** Whether this tab is the bar's current selection. */
3231
+ readonly active: import("@angular/core").Signal<boolean>;
3232
+ /** `aria-current` of the link form: `page` while the active tab's root page is shown, `true`
3233
+ * while a child page of it is (the tab is the current section, not the current page), else
3234
+ * `null`. */
3235
+ readonly current: import("@angular/core").Signal<"page" | "true" | null>;
3236
+ /** The badge as announced after the label in the accessible name when `badge()` is set. */
3237
+ readonly badgeAnnouncement: import("@angular/core").Signal<string | null>;
3238
+ /**
3239
+ * The tab's accessible name while a badge is set, `"{label}, {announcement}"` ("Projects, 3
3240
+ * new"), as `aria-label`: one string, so no browser inserts a pause before the comma (a visually
3241
+ * hidden span is block-level, and Chromium and WebKit join block children with a space). `null`
3242
+ * without a badge, so the name is the visible label.
3243
+ */
3244
+ readonly accessibleName: import("@angular/core").Signal<string | null>;
3245
+ readonly buttonClasses: import("@angular/core").Signal<string>;
3246
+ readonly capsuleClasses: import("@angular/core").Signal<string>;
3247
+ readonly labelClasses: import("@angular/core").Signal<string>;
3248
+ /** Moves keyboard focus to this tab's button (or link); called by `bf-tab-bar` after arrow-key
3249
+ * selection. */
3250
+ focus(): void;
3251
+ /**
3252
+ * A plain primary click on the link selects the tab through the bar (so `bf-tabs` restores the
3253
+ * tab's stack, plays its haptic and pops to the root on reselect) instead of following `href`. A
3254
+ * modified or non-primary click (Ctrl/Cmd, Shift, Alt, middle) is left to the browser, which
3255
+ * opens the tab's URL in a new tab or window.
3256
+ * @internal
3257
+ */
3258
+ onLinkClick(event: MouseEvent): void;
3259
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfTabComponent, never>;
3260
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfTabComponent, "bf-tab", never, {
3261
+ "id": {
3262
+ "alias": "id";
3263
+ "required": true;
3264
+ "isSignal": true;
3265
+ };
3266
+ "label": {
3267
+ "alias": "label";
3268
+ "required": true;
3269
+ "isSignal": true;
3270
+ };
3271
+ "badge": {
3272
+ "alias": "badge";
3273
+ "required": false;
3274
+ "isSignal": true;
3275
+ };
3276
+ "disabled": {
3277
+ "alias": "disabled";
3278
+ "required": false;
3279
+ "isSignal": true;
3280
+ };
3281
+ }, {}, never, ["*"], true, never>;
3282
+ }
3283
+ /**
3284
+ * Floating pill tab bar for mobile apps (Meadow Sage): at least 64 px tall (it grows with a label
3285
+ * wrapped to two lines at large text sizes; at least 48 px, with icon and label side by side, at
3286
+ * compact heights such as phone landscape), inset 14 px from the sides and
3287
+ * 8 px above the bottom safe area (at least 12 px, so 20 px from the edge without an inset), one
3288
+ * `bf-tab` per destination. On its own it is a pure control with an `active` model and a `hidden`
3289
+ * input: a `tablist` whose selection follows focus with the arrow keys. Inside `bf-tabs`, which
3290
+ * provides `BF_TAB_LINKS` and `BF_TAB_BAR_CONTROLLER`, it is a `nav` of links with `aria-current`
3291
+ * on the active tab (`page` on its root page, `true` on a child page of it) whose selection and
3292
+ * hiding derive from the router and the keyboard; `active` is not written there.
3293
+ *
3294
+ * @example
3295
+ * <bf-tab-bar [(active)]="tab" (changed)="go($event)">
3296
+ * <bf-tab id="today" label="Today"><bf-icon [icon]="Sun" /></bf-tab>
3297
+ * <bf-tab id="inbox" label="Inbox" [badge]="3"><bf-icon [icon]="Inbox" /></bf-tab>
3298
+ * </bf-tab-bar>
3299
+ * @summary Floating pill tab bar for mobile apps with arrow-key selection and count badges
3300
+ * @category Navigation
3301
+ * @since 0.1.0
3302
+ * @slot default The tabs, each a `bf-tab`.
3303
+ */
3304
+ export declare class BfTabBarComponent implements BfTabBarHost {
3305
+ /** The active tab's id; two-way bindable. */
3306
+ readonly active: import("@angular/core").ModelSignal<string>;
3307
+ /** Accessible name of the navigation; empty falls back to `provideBfLabels()`'s `tabBar`
3308
+ * ("Main"). */
3309
+ readonly label: import("@angular/core").InputSignal<string>;
3310
+ private readonly labels;
3311
+ /** The rendered navigation name: `label`, else the `tabBar` label. */
3312
+ readonly name: import("@angular/core").Signal<string>;
3313
+ /** Floats fixed above the safe area with a shadow; false renders it inline in the layout flow. */
3314
+ readonly floating: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
3315
+ /**
3316
+ * Slides the bar down out of view (e.g. while the soft keyboard is open); `aria-hidden` and inert
3317
+ * while hidden. Shadows the global `hidden` attribute on purpose: a static `<bf-tab-bar hidden>`
3318
+ * sets this input (the slide) and the attribute itself is removed from the host, so it never
3319
+ * becomes `display: none`.
3320
+ */
3321
+ readonly hidden: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
3322
+ /** Animates hiding and showing (200 ms `translate-y`/`opacity`); false switches instantly. */
3323
+ readonly hideTransition: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
3324
+ /** Emitted with the newly selected tab's id after a user change. */
3325
+ readonly changed: import("@angular/core").OutputEmitterRef<string>;
3326
+ /** Emitted with the active tab's id when the user selects the tab that is already active. */
3327
+ readonly reselected: import("@angular/core").OutputEmitterRef<string>;
3328
+ /**
3329
+ * Emitted with the newly selected tab's id after a user change, together with `changed`.
3330
+ * @deprecated 0.3.0 use changed; removed in 0.4.0
3331
+ */
3332
+ readonly tabChange: import("@angular/core").OutputEmitterRef<string>;
3333
+ /**
3334
+ * Emitted with the active tab's id on a reselect, together with `reselected`.
3335
+ * @deprecated 0.3.0 use reselected; removed in 0.4.0
3336
+ */
3337
+ readonly tabReselect: import("@angular/core").OutputEmitterRef<string>;
3338
+ private readonly links;
3339
+ /** True inside a router-aware parent (`bf-tabs`): the tabs are links, not a tablist. */
3340
+ readonly linkMode: boolean;
3341
+ private readonly controller;
3342
+ private readonly hiddenState;
3343
+ private readonly hideTransitionState;
3344
+ /** The id of the tab shown as selected: the controller's `current()` inside `bf-tabs` (empty
3345
+ * while it is unknown), else `active`. */
3346
+ readonly selected: import("@angular/core").Signal<string>;
3347
+ /** True while the bar is hidden, through the `hidden` input, `setHidden()` or the controller. */
3348
+ readonly isHidden: import("@angular/core").Signal<boolean>;
3349
+ /** The `bf-tab` children projected into the bar, in document order. */
3350
+ readonly tabs: import("@angular/core").Signal<readonly BfTabComponent[]>;
3351
+ /** The id that currently owns the roving tab stop: the active enabled tab, or the first enabled
3352
+ * tab when nothing valid is selected (empty `active`, before a router binding resolves, or the
3353
+ * active tab is disabled). */
3354
+ readonly tabStop: import("@angular/core").Signal<string>;
3355
+ readonly navClasses: import("@angular/core").Signal<string>;
3356
+ /**
3357
+ * The imperative counterpart of the `hidden` input, for a parent that projects the bar and so
3358
+ * cannot bind it (`bf-tabs` provides `BF_TAB_BAR_CONTROLLER` instead). The bar is hidden while
3359
+ * the input, this or the controller's `hidden()` is true; `transition` overrides
3360
+ * `hideTransition` when given.
3361
+ * @param hidden Whether to hide the bar.
3362
+ * @param transition Whether the change animates (default: `hideTransition`).
3363
+ */
3364
+ setHidden(hidden: boolean, transition?: boolean): void;
3365
+ /**
3366
+ * Selects `id` and emits `changed`, or `reselected` when `id` is already selected; ignores
3367
+ * disabled or unknown tab ids. Inside `bf-tabs` it hands the selection to the controller
3368
+ * (`select`/`reselect`) instead of writing `active`.
3369
+ * @param id The `id` of the tab to select.
3370
+ */
3371
+ select(id: string): void;
3372
+ /**
3373
+ * The URL of tab `id` in link mode (`BF_TAB_LINKS`); `null` for a standalone bar.
3374
+ * @param id The `id` of the tab.
3375
+ */
3376
+ linkHref(id: string): string | null;
3377
+ /**
3378
+ * Whether the current page is tab `id`'s root page (link mode); `true` for a standalone bar.
3379
+ * @param id The `id` of the tab.
3380
+ */
3381
+ linkIsRoot(id: string): boolean;
3382
+ /**
3383
+ * Arrow keys, Home and End move focus and selection along the tabs.
3384
+ * @internal
3385
+ */
3386
+ onKeydown(event: KeyboardEvent): void;
3387
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfTabBarComponent, never>;
3388
+ static ɵcmp: i0.ɵɵComponentDeclaration<BfTabBarComponent, "bf-tab-bar", never, {
3389
+ "active": {
3390
+ "alias": "active";
3391
+ "required": false;
3392
+ "isSignal": true;
3393
+ };
3394
+ "label": {
3395
+ "alias": "label";
3396
+ "required": false;
3397
+ "isSignal": true;
3398
+ };
3399
+ "floating": {
3400
+ "alias": "floating";
3401
+ "required": false;
3402
+ "isSignal": true;
3403
+ };
3404
+ "hidden": {
3405
+ "alias": "hidden";
3406
+ "required": false;
3407
+ "isSignal": true;
3408
+ };
3409
+ "hideTransition": {
3410
+ "alias": "hideTransition";
3411
+ "required": false;
3412
+ "isSignal": true;
3413
+ };
3414
+ }, {
3415
+ "active": "activeChange";
3416
+ "changed": "changed";
3417
+ "reselected": "reselected";
3418
+ "tabChange": "tabChange";
3419
+ "tabReselect": "tabReselect";
3420
+ }, ["tabs"], ["*"], true, never>;
3421
+ }
3422
+ /**
3423
+ * The one interactive element of a `bf-card` or `bf-list-item` (the stretched-link pattern): put
3424
+ * it on the `<a>` (navigation) or `<button>` (an action) that holds the card's heading text or the
3425
+ * row's title. Its `::after` stretches the hit area over the nearest positioned ancestor (the card
3426
+ * box, the row), so the whole surface is clickable while only the heading's link or button is
3427
+ * exposed: the heading stays a heading and the accessible name is the title alone. It registers
3428
+ * with the nearest card or row, which then draws the pointer, the hover and, while the action has
3429
+ * keyboard focus, the focus ring; a card is never lit by the actions of rows nested in it. Give
3430
+ * secondary controls inside the surface `class="relative z-1"` so they stay clickable above the
3431
+ * stretched area.
3432
+ *
3433
+ * @example
3434
+ * <bf-card>
3435
+ * <h3 class="text-heading"><a bfAction routerLink="/projects/atlas">Atlas rebrand</a></h3>
3436
+ * </bf-card>
3437
+ * @summary Makes one link or button the click target of a whole card or list row
3438
+ * @since 0.3.0
3439
+ */
3440
+ export declare class BfActionDirective {
3441
+ private readonly host;
3442
+ private readonly element;
3443
+ constructor();
3444
+ /**
3445
+ * Tells the host card or row whether its action has keyboard focus.
3446
+ * @internal
3447
+ */
3448
+ onFocus(): void;
3449
+ /**
3450
+ * Tells the host card or row that its action lost focus.
3451
+ * @internal
3452
+ */
3453
+ onBlur(): void;
3454
+ static ɵfac: i0.ɵɵFactoryDeclaration<BfActionDirective, never>;
3455
+ static ɵdir: i0.ɵɵDirectiveDeclaration<BfActionDirective, "a[bfAction], button[bfAction]", never, {}, {}, never, never, true, never>;
3456
+ }
3457
+ /** An error as a field reads it: its kind and optional message; limit fields (`minLength`,
3458
+ * `context.requiredLength`, …) are read through type guards by `bfValidationMessage`. */
3459
+ type FieldErrorLike = Pick<ValidationError, 'kind' | 'message'>;
3460
+ /**
3461
+ * Explicit error message wins; otherwise, once the field was touched, the first form error's text:
3462
+ * its own `message`, else the default for its kind from `messages` (`BF_LABELS.validation`).
3463
+ */
3464
+ declare function fieldErrorText(errorMessage: string, touched: boolean, errors: readonly FieldErrorLike[], messages: BfValidationMessages): string;
3465
+ /** The visual error state: any error text, or a field the form marked invalid after it was touched. */
3466
+ declare function fieldShowsError(errorText: string, invalid: boolean, touched: boolean): boolean;
3467
+ /**
3468
+ * `aria-describedby` targets: the help paragraph and the error paragraph under it, each while it
3469
+ * is rendered (`"<id>-help <id>-error"`, `"<id>-help"`, `"<id>-error"`), else none.
3470
+ */
3471
+ declare function fieldDescribedBy(id: string, errorText: string, helpText: string): string | null;
3472
+ /** `aria-errormessage` target: the error paragraph while the control is invalid, else none. */
3473
+ declare function fieldErrorMessageId(id: string, errorText: string, showError: boolean): string | null;
3474
+ /**
3475
+ * Returns a document-unique id such as `bf-input-3`, for associating labels and hints with controls.
3476
+ *
3477
+ * The ids come from this module-level counter, so a server render and the client (or two server
3478
+ * renders in one process) number them differently: `@bitforgehq/ui` 0.x is client-rendered only,
3479
+ * and SSR, hydration and prerendering of pages that render its components are not supported.
3480
+ * Hydration-stable ids are decided before 1.0.
3481
+ */
3482
+ declare function uniqueId(prefix: string): string;
3483
+ /** The positioned, empty ::after that carries the extension; add one inset class beside it. */
3484
+ declare const COARSE_HIT_BASE = "pointer-coarse:after:absolute pointer-coarse:after:inset-x-0 pointer-coarse:after:content-['']";
3485
+ /**
3486
+ * Vertical hit extension of a 32/40/48 px pill, to 44 px under a coarse pointer. `bordered` boxes
3487
+ * (1.5 px border) position the ::after inside the border, so their inset adds the border back.
3488
+ */
3489
+ declare const PILL_HIT: Record<BfSize, Record<'plain' | 'bordered', string>>;
3490
+ /**
3491
+ * Removes what overlays and themes leave on a document: the `dark` and `cdk-global-scrollblock`
3492
+ * classes on `<html>`, `inert` on the children of `<body>`, and every child of a
3493
+ * `.cdk-overlay-container`. Internal: shared by `provideBfTesting()` (`@bitforgehq/ui/testing`)
3494
+ * and `provideBfShellTesting()` (`@bitforgehq/ui/mobile`).
3495
+ */
3496
+ declare function resetBfDocument(document: Document): void;
3497
+ /** Runs `resetBfDocument()` when the environment injector that holds it is destroyed. Internal. */
3498
+ declare function provideBfDocumentReset(): EnvironmentProviders;
3499
+ export { type BfAlertVariant, type BfAutocapitalize, type BfAvatarSize, type BfAvatarVariant, type BfBadgeVariant, type BfButtonSize, type BfButtonType, type BfButtonVariant, type BfCardPadding, type BfCardVariant, type BfChipGroupMode, type BfChipVariant, type BfCompareWith, type BfDefaults, type BfDefaultsOptions, type BfEmptyStateHeadingLevel, type BfEnterKeyHint, type BfFieldControlState, type BfFieldSize, type BfIconButtonVariant, type BfInputAutocapitalize, type BfInputEnterKeyHint, type BfInputInputMode, type BfInputMode, type BfInputType, type BfLabels, type BfLabelsOverrides, type BfProgressSize, type BfProgressTone, type BfRadioGroupOrientation, type BfRadioOption, type BfSegmentOption, type BfSegmentedSize, type BfSelectOption, type BfSize, type BfSpinnerSize, type BfTabBarController, type BfTabBarHost, type BfTabLinks, type BfToggleLabelPosition, type BfValidationMessages, BUTTON_CLASSES as ɵBF_BUTTON_CLASSES, ICON_BUTTON_CLASSES as ɵBF_ICON_BUTTON_CLASSES, FIELD_BOX as ɵFIELD_BOX, FIELD_ICON_END as ɵFIELD_ICON_END, FIELD_ICON_START as ɵFIELD_ICON_START, FIELD_PADDING_END as ɵFIELD_PADDING_END, FIELD_PADDING_START as ɵFIELD_PADDING_START, PILL_HIT as ɵPILL_HIT, fieldDescribedBy as ɵfieldDescribedBy, fieldErrorMessageId as ɵfieldErrorMessageId, fieldErrorText as ɵfieldErrorText, fieldShowsError as ɵfieldShowsError, provideBfDocumentReset as ɵprovideBfDocumentReset, uniqueId as ɵuniqueId };