@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,163 @@
1
+ # BfOverscrollStretchDirective
2
+
3
+ Android-style stretch of a scroll container dragged past its top or bottom edge
4
+
5
+ Directive from `@bitforgehq/ui/mobile` · since 0.2.0
6
+
7
+ Android-style edge stretch for a scroll container: a vertical touch drag past the top or bottom
8
+ edge scales the container's first element child (the content body) up along the y axis from
9
+ that edge — `scaleY(1 + 0.14 × (1 − e^(−pull / 240)))` — and springs it back on release (220 ms,
10
+ the settle curve; instant under `prefers-reduced-motion`). Touch only, with passive listeners:
11
+ it never prevents a touch, so scrolling is untouched. It follows the finger that started the
12
+ gesture and ignores any other. A horizontal-dominant gesture (decided after 8 px) is ignored,
13
+ and the top edge is left alone while an active `bf-refresher` (`[data-bf-refresher]`) inside
14
+ the container owns the top pull. `bf-content` applies it to its
15
+ scroller in Material mode, where the WebView draws no overscroll effect of its own.
16
+
17
+ ```ts
18
+ import { BfOverscrollStretchDirective } from '@bitforgehq/ui/mobile';
19
+ ```
20
+
21
+ Selector: `[bfOverscrollStretch]`
22
+
23
+ Android-style edge stretch for a scroll container. Android 12+ stretches a native list at the edge
24
+ under the finger and springs it back, but an Android WebView draws no overscroll effect at all for
25
+ an inner scroller. `bfOverscrollStretch` adds it: pull past the top or bottom edge and the
26
+ container's first element child (the content body) stretches from that edge. `bf-content` applies
27
+ it to its own scroller in Material mode, so most pages never use it directly; put it on a custom
28
+ scroll container only when that container is not a `bf-content`.
29
+
30
+ ## When to use
31
+
32
+ Use `bfOverscrollStretch` on a custom scroll container in an Android Capacitor app, for the native edge stretch. Use [bf-content](https://bitforge-ui.web.app/components/content) instead for a normal page, which applies it already in Material mode.
33
+
34
+ ## Basic usage
35
+
36
+ ```ts
37
+ import { Component } from '@angular/core';
38
+ import { BfListComponent, BfListItemComponent } from '@bitforgehq/ui';
39
+ import { BfOverscrollStretchDirective } from '@bitforgehq/ui/mobile';
40
+
41
+ /**
42
+ * A scroller whose body stretches at the ends.
43
+ *
44
+ * The directive moves the scroller's first child, so the content sits in one block body.
45
+ *
46
+ * @preview none
47
+ */
48
+ @Component({
49
+ selector: 'app-example-overscroll-stretch-basic',
50
+ imports: [BfListComponent, BfListItemComponent, BfOverscrollStretchDirective],
51
+ template: `
52
+ <div class="h-full overflow-y-auto" bfOverscrollStretch>
53
+ <div>
54
+ <bf-list>
55
+ <bf-list-item title="Inbox" />
56
+ <bf-list-item title="Archive" />
57
+ </bf-list>
58
+ </div>
59
+ </div>
60
+ `,
61
+ })
62
+ export class OverscrollStretchBasicExampleComponent {}
63
+ ```
64
+
65
+ The directive transforms the host's **first element child**, so wrap the content in one block
66
+ element; the host itself never moves.
67
+
68
+ ## How it works
69
+
70
+ - **Touch only.** It listens to `touchstart`, `touchmove`, `touchend` and `touchcancel` on the
71
+ host, all passive, and never prevents a touch: a pull at an edge scrolls nothing natively, so
72
+ there is nothing to cancel. Mouse and pen do nothing. It follows the finger that started the
73
+ gesture (by `Touch.identifier`) and ends when that finger lifts; a second finger is ignored.
74
+ - **Axis.** Once the finger has moved 8 px from where it started, the gesture is vertical or
75
+ horizontal for good. A horizontal-dominant gesture (a horizontal scroller, a swipe) is ignored.
76
+ - **Pull.** At the top (`scrollTop <= 0`) a downward move adds to the pull, stretching from the
77
+ top; at the bottom (`scrollTop >= scrollHeight − clientHeight − 1`) an upward move adds to it,
78
+ stretching from the bottom. Moving the finger back takes the pull down towards 0 (the list then
79
+ simply scrolls); away from both edges the pull is 0.
80
+ - **Stretch.** The body gets `transform: scaleY(1 + 0.14 × (1 − e^(−pull / 240)))` with
81
+ `transform-origin: center top` or `center bottom`, and `will-change: transform` for the
82
+ gesture only. It approaches 1.14 and never passes it.
83
+ - **Release.** It springs back to `scaleY(1)` with the Web Animations API (220 ms,
84
+ `cubic-bezier(0.2, 0.8, 0.3, 1)`), then clears `transform`, `transform-origin` and
85
+ `will-change`. A new touch during the spring-back resets it at once.
86
+ - **Refresher.** While an enabled `bf-refresher` (`[data-bf-refresher]`) is inside the container,
87
+ the top pull belongs to it: only the bottom edge stretches.
88
+ - **Engine, not shell mode.** `bf-content` turns the stretch on from the engine
89
+ (`BfPlatformService.mode()`, and off in iOS WebKit), not from `provideBfShell({ mode })`: WebKit
90
+ rubber-bands on its own, while Chrome never reports a negative `scrollTop` and draws nothing, so
91
+ an Android app forced into `mode: 'ios'` still stretches and an iOS app forced into `mode: 'md'`
92
+ never stacks the stretch on the bounce.
93
+
94
+ ## Turning it off
95
+
96
+ `bfOverscrollStretch` takes a boolean (`true` when the attribute is bare); `false` leaves the
97
+ directive inert. Bind it to the platform to stretch on Android only, where iOS already bounces
98
+ natively. The input table is in the directive's API reference.
99
+
100
+ ```ts
101
+ import { Component, inject } from '@angular/core';
102
+ import { BfListComponent, BfListItemComponent } from '@bitforgehq/ui';
103
+ import { BfOverscrollStretchDirective, BfPlatformService } from '@bitforgehq/ui/mobile';
104
+
105
+ /**
106
+ * The stretch on Android only.
107
+ *
108
+ * `[bfOverscrollStretch]` takes a boolean; iOS already bounces natively.
109
+ *
110
+ * @preview none
111
+ */
112
+ @Component({
113
+ selector: 'app-example-overscroll-stretch-conditional',
114
+ imports: [BfListComponent, BfListItemComponent, BfOverscrollStretchDirective],
115
+ template: `
116
+ <div class="h-full overflow-y-auto" [bfOverscrollStretch]="isAndroid">
117
+ <div>
118
+ <bf-list>
119
+ <bf-list-item title="Inbox" />
120
+ </bf-list>
121
+ </div>
122
+ </div>
123
+ `,
124
+ })
125
+ export class OverscrollStretchConditionalExampleComponent {
126
+ protected readonly isAndroid = inject(BfPlatformService).platform === 'android';
127
+ }
128
+ ```
129
+
130
+ ## Desktop
131
+
132
+ The stretch follows touch events only, so a mouse, a trackpad or the keyboard never starts it; on desktop the directive does nothing. Leave it out of desktop layouts.
133
+
134
+ ## Theming
135
+
136
+ None — it writes only inline `transform`, `transform-origin` and `will-change` on the first
137
+ element child during a gesture and its spring-back, and removes them afterwards. Do not rely on
138
+ your own inline transform on that element.
139
+
140
+ ## Accessibility
141
+
142
+ Pure feel, no behaviour: the stretch changes nothing that is read, focused or scrolled, and it
143
+ never prevents a touch. Under `prefers-reduced-motion: reduce` the stretch still follows the
144
+ finger (direct manipulation is not motion), but the spring-back is an instant reset.
145
+
146
+ ## Notes
147
+
148
+ ### Do
149
+
150
+ - Rely on `bf-content`'s built-in stretch in Material mode; add the directive only to a custom
151
+ scroll container.
152
+ - Wrap the scrollable content in a single block element, the one that stretches.
153
+
154
+ ### Don't
155
+
156
+ - Don't use it in iOS mode, where WebKit's own rubber band already bounces the scroller.
157
+ - Don't put it on an element that does not scroll vertically.
158
+
159
+ ## Inputs
160
+
161
+ | Name | Type | Default | Description |
162
+ | --------------------- | --------- | ------- | ------------------------------------------------------ |
163
+ | `bfOverscrollStretch` | `boolean` | `true` | Enables the stretch; false leaves the container inert. |
@@ -0,0 +1,24 @@
1
+ # BfPageContext
2
+
3
+ Per-page state that the header and content of one page share
4
+
5
+ Class from `@bitforgehq/ui/mobile` · since 0.2.0
6
+
7
+ Per-page state shared between the parts of one `bf-page`. `bf-page` provides a fresh instance
8
+ for each page through its element injector; `bf-content` registers its scroll container here
9
+ on init (and clears it on destroy), so siblings such as `bf-header` can follow the page's
10
+ scroll without querying the DOM. A plain class, like `BfViewLifecycle`: it is only ever
11
+ provided per page, never from the root injector.
12
+
13
+ ```ts
14
+ import { BfPageContext } from '@bitforgehq/ui/mobile';
15
+ ```
16
+
17
+ ## Properties
18
+
19
+ | Name | Type | Default | Description |
20
+ | -------------- | ------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
21
+ | `scroller` | `WritableSignal<HTMLElement \| null>` | | The page's scroll container (`bf-content`'s scroller), or `null` before one registers. |
22
+ | `headerHeight` | `WritableSignal<number>` | | Height (px) of a `translucent` `bf-header` drawn over the content, which `bf-content` pads its scroller by (`--bf-header-height`); 0 while the header sits in the page's flow (or none). |
23
+ | `safeAreaTop` | `WritableSignal<boolean>` | | Whether the page reaches the top of the screen, so its `bf-header` toolbar (and a `fullscreen` `bf-content`) pads by the top safe area. True for a page; `bf-modal` in the `sheet` presentation sets it to false, because its card already sits below the status bar. |
24
+ | `mainLandmark` | `WritableSignal<boolean>` | | Whether the page's `bf-content` scroller is the document's `main` landmark (`role="main"`). True for the page a `bf-stack-outlet` shows; `bf-modal` sets it to false (content in a dialog is not `main`), and so does a `bf-page` outside an outlet (a docs illustration) or nested in another page, so the document keeps exactly one `main`: parked pages are `inert` and `aria-hidden`, so only the shown page's landmark is exposed. |
@@ -0,0 +1,53 @@
1
+ # BfPlatformService
2
+
3
+ Platform facts and the app theme: native or web, iOS or Android, light or dark
4
+
5
+ Service from `@bitforgehq/ui/mobile` · since 0.2.0
6
+
7
+ Platform facts and the app theme: native or web, iOS or Android, the shell mode that follows
8
+ from it, and the user's theme choice (system, light, dark) reflected as the `dark` class on
9
+ `<html>`. `matchMedia('(prefers-color-scheme: dark)')` is the single source for the system
10
+ theme on every platform.
11
+
12
+ The `theme`/`dark` signals always compute, but the `<html>` class and storage writes
13
+ only run when `provideBfShell()` provided `BF_SHELL_CONFIG` — i.e. this service is the app's
14
+ own shell, not merely injected by something that wants `platform`/`mode`. Without it (e.g. a
15
+ docs demo that instantiates `BfPlatformService` directly to preview `bf-tabs`), this service
16
+ would otherwise fight the host page's own theme: its `effect` runs on construction and would
17
+ immediately overwrite `<html class="dark">` with whatever `prefers-color-scheme` says.
18
+
19
+ With `provideBfShell()` on a native platform it also makes the viewport meta forbid zoom
20
+ (`maximum-scale=1, user-scalable=no`, other directives kept; the meta is created if missing):
21
+ WKWebView zooms a focused control whose font is under 16 px and never zooms back, so the native
22
+ shell forbids zoom — pinch, double tap and focus alike — and honours the system text size
23
+ instead (iOS Dynamic Type through `BfTextScaleService`, Android's font scale in the WebView).
24
+ On the web the meta is never touched, so a web build keeps pinch zoom (the owner's ruling,
25
+ audit §12): ship `index.html` without `maximum-scale`/`user-scalable`.
26
+
27
+ With `provideBfShell()` on native iOS and Android (unless `syncSystemBars: false`) the status-bar
28
+ and navigation-bar icons follow `dark()`: `SystemBars.setStyle()` with `bfSystemBarsStyle()`,
29
+ on start and on every theme change (Android WebView < 140 keeps `Default`, see there).
30
+
31
+ ```ts
32
+ import { BfPlatformService } from '@bitforgehq/ui/mobile';
33
+ ```
34
+
35
+ ## Properties
36
+
37
+ | Name | Type | Default | Description |
38
+ | ---------- | -------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------- |
39
+ | `isNative` | `boolean` | | True inside the native iOS or Android app, false in a browser. |
40
+ | `platform` | `BfPlatform` (`'ios' \| 'android' \| 'web'`) | | The platform the app runs on. |
41
+ | `mode` | `Signal<BfShellMode>` | | The platform's shell mode: `ios` on iOS, else `md`; `resolveShellMode()` applies the config. |
42
+ | `theme` | `WritableSignal<BfTheme>` | | The user's theme choice, stored in `BF_THEME_STORAGE` (`localStorage`); set it with `theme.set(…)`. |
43
+ | `dark` | `Signal<boolean>` | | Whether the app is dark now: the theme choice, or the system's under `system`. |
44
+
45
+ ## Uses
46
+
47
+ - [BfPlatform](bf-platform.md)
48
+ - [BfShellMode](bf-shell-mode.md)
49
+ - [BfTheme](bf-theme.md)
50
+
51
+ ## Used by
52
+
53
+ - [resolveShellMode](resolve-shell-mode.md)
@@ -0,0 +1,28 @@
1
+ # BfPlatform
2
+
3
+ The platform the app runs on, native iOS, native Android or the web
4
+
5
+ Type from `@bitforgehq/ui/mobile` · since 0.2.0
6
+
7
+ The platform the app runs on: native iOS, native Android, or a browser.
8
+
9
+ ```ts
10
+ import { type BfPlatform } from '@bitforgehq/ui/mobile';
11
+ ```
12
+
13
+ ## Signature
14
+
15
+ ```ts
16
+ type BfPlatform = 'ios' | 'android' | 'web'
17
+ ```
18
+
19
+ ## Values
20
+
21
+ - `ios`
22
+ - `android`
23
+ - `web`
24
+
25
+ ## Used by
26
+
27
+ - [BfPlatformService](bf-platform-service.md)
28
+ - [bfSystemBarsStyle](bf-system-bars-style.md)
@@ -0,0 +1,26 @@
1
+ # BfProgressSize
2
+
3
+ The two track heights of a progress bar, thin and regular
4
+
5
+ Type from `@bitforgehq/ui` · since 0.1.0
6
+
7
+ The track height of a `bf-progress`: sm or md.
8
+
9
+ ```ts
10
+ import { type BfProgressSize } from '@bitforgehq/ui';
11
+ ```
12
+
13
+ ## Signature
14
+
15
+ ```ts
16
+ type BfProgressSize = 'sm' | 'md'
17
+ ```
18
+
19
+ ## Values
20
+
21
+ - `sm`
22
+ - `md`
23
+
24
+ ## Used by
25
+
26
+ - [bf-progress](../components/progress.md)
@@ -0,0 +1,28 @@
1
+ # BfProgressTone
2
+
3
+ The four fill colours of a progress bar, from primary to danger
4
+
5
+ Type from `@bitforgehq/ui` · since 0.1.0
6
+
7
+ The fill colour of a `bf-progress`: primary, success, warning or danger.
8
+
9
+ ```ts
10
+ import { type BfProgressTone } from '@bitforgehq/ui';
11
+ ```
12
+
13
+ ## Signature
14
+
15
+ ```ts
16
+ type BfProgressTone = 'primary' | 'success' | 'warning' | 'danger'
17
+ ```
18
+
19
+ ## Values
20
+
21
+ - `primary`
22
+ - `success`
23
+ - `warning`
24
+ - `danger`
25
+
26
+ ## Used by
27
+
28
+ - [bf-progress](../components/progress.md)
@@ -0,0 +1,49 @@
1
+ # BfRadioGroupHarness
2
+
3
+ Test harness for the radio group: reads its options and selects one by label
4
+
5
+ Class from `@bitforgehq/ui/testing` · since 0.3.0
6
+
7
+ Harness for `bf-radio-group`. It works by option label, so a test never needs the native radio
8
+ values (an object option's native value is its index).
9
+
10
+ ```ts
11
+ import { BfRadioGroupHarness } from '@bitforgehq/ui/testing';
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```ts
17
+ class BfRadioGroupHarness extends ComponentHarness
18
+ ```
19
+
20
+ ## Methods
21
+
22
+ ### `getLabel(): Promise<string>`
23
+
24
+ The legend, else the group's `aria-label`.
25
+
26
+ ### `getOptionLabels(): Promise<string[]>`
27
+
28
+ The labels of the options, in order.
29
+
30
+ ### `getSelectedLabel(): Promise<string | null>`
31
+
32
+ The selected option's label, `null` while nothing is selected.
33
+
34
+ ### `select(label: string): Promise<void>`
35
+
36
+ Clicks the option with this label, as a user would. Throws for an unknown label, and for a
37
+ disabled option or group (a user's click would do nothing).
38
+
39
+ | Parameter | Type | Description |
40
+ | --------- | -------- | ------------------- |
41
+ | `label` | `string` | The option's label. |
42
+
43
+ ### `isDisabled(): Promise<boolean>`
44
+
45
+ Whether the whole group is disabled.
46
+
47
+ ### `getErrorText(): Promise<string>`
48
+
49
+ The error text under the options.
@@ -0,0 +1,26 @@
1
+ # BfRadioGroupOrientation
2
+
3
+ Whether a radio group stacks its options or sets them in a row
4
+
5
+ Type from `@bitforgehq/ui` · since 0.3.0
6
+
7
+ How a `bf-radio-group` lays out its options: stacked (`vertical`) or in a row (`horizontal`).
8
+
9
+ ```ts
10
+ import { type BfRadioGroupOrientation } from '@bitforgehq/ui';
11
+ ```
12
+
13
+ ## Signature
14
+
15
+ ```ts
16
+ type BfRadioGroupOrientation = 'vertical' | 'horizontal'
17
+ ```
18
+
19
+ ## Values
20
+
21
+ - `vertical`
22
+ - `horizontal`
23
+
24
+ ## Used by
25
+
26
+ - [bf-radio-group](../components/radio-group.md)
@@ -0,0 +1,30 @@
1
+ # BfRadioOption
2
+
3
+ One choice of a radio group with its value, label and optional description
4
+
5
+ Interface from `@bitforgehq/ui` · since 0.1.0
6
+
7
+ One choice of `bf-radio-group`; `value` is any type (a string by default).
8
+
9
+ ```ts
10
+ import { type BfRadioOption } from '@bitforgehq/ui';
11
+ ```
12
+
13
+ ## Signature
14
+
15
+ ```ts
16
+ interface BfRadioOption<T = string>
17
+ ```
18
+
19
+ ## Properties
20
+
21
+ | Name | Type | Default | Description |
22
+ | ------------- | --------- | -------- | --------------------------------------------------------------------------- |
23
+ | `value` | `T` | required | The value the group's `value` takes when this option is chosen. |
24
+ | `label` | `string` | required | The visible label, also the radio's accessible name. |
25
+ | `description` | `string` | | A second line under the label, linked to the radio with `aria-describedby`. |
26
+ | `disabled` | `boolean` | | Whether this option cannot be chosen. |
27
+
28
+ ## Used by
29
+
30
+ - [bf-radio-group](../components/radio-group.md)
@@ -0,0 +1,22 @@
1
+ # BfRefresherRefreshEvent
2
+
3
+ What a pull-to-refresh request carries: the callback that ends the refresh
4
+
5
+ Interface from `@bitforgehq/ui/mobile` · since 0.3.0
6
+
7
+ The payload of `bf-refresher`'s `refreshRequested` output: call `complete()` once the reload is
8
+ done to animate the disc away.
9
+
10
+ ```ts
11
+ import { type BfRefresherRefreshEvent } from '@bitforgehq/ui/mobile';
12
+ ```
13
+
14
+ ## Properties
15
+
16
+ | Name | Type | Default | Description |
17
+ | ---------- | ------------ | -------- | ------------------------------------------------------------------ |
18
+ | `complete` | `() => void` | required | Ends the refresh: animates the disc away and resets the refresher. |
19
+
20
+ ## Used by
21
+
22
+ - [bf-refresher](../components/refresher.md)
@@ -0,0 +1,29 @@
1
+ # BfSegmentOption
2
+
3
+ One segment of a segmented control with its value, its label and a disabled flag
4
+
5
+ Interface from `@bitforgehq/ui` · since 0.1.0
6
+
7
+ One segment of `bf-segmented`; `value` is any type (a string by default).
8
+
9
+ ```ts
10
+ import { type BfSegmentOption } from '@bitforgehq/ui';
11
+ ```
12
+
13
+ ## Signature
14
+
15
+ ```ts
16
+ interface BfSegmentOption<T = string>
17
+ ```
18
+
19
+ ## Properties
20
+
21
+ | Name | Type | Default | Description |
22
+ | ---------- | --------- | -------- | -------------------------------------------------------------------- |
23
+ | `value` | `T` | required | The value the control's `value` takes when this segment is selected. |
24
+ | `label` | `string` | required | The segment's visible label, also its accessible name. |
25
+ | `disabled` | `boolean` | | Whether this segment cannot be selected. |
26
+
27
+ ## Used by
28
+
29
+ - [bf-segmented](../components/segmented.md)
@@ -0,0 +1,48 @@
1
+ # BfSegmentedHarness
2
+
3
+ Test harness for the segmented control: reads its segments and selects one
4
+
5
+ Class from `@bitforgehq/ui/testing` · since 0.3.0
6
+
7
+ Harness for `bf-segmented`. It works by segment label, so a test never needs the option values.
8
+
9
+ ```ts
10
+ import { BfSegmentedHarness } from '@bitforgehq/ui/testing';
11
+ ```
12
+
13
+ ## Signature
14
+
15
+ ```ts
16
+ class BfSegmentedHarness extends ComponentHarness
17
+ ```
18
+
19
+ ## Methods
20
+
21
+ ### `getLabel(): Promise<string>`
22
+
23
+ The group's accessible name (`label`, else `ariaLabel`); it is not rendered visibly.
24
+
25
+ ### `getOptionLabels(): Promise<string[]>`
26
+
27
+ The labels of the segments, in order.
28
+
29
+ ### `getSelectedLabel(): Promise<string | null>`
30
+
31
+ The selected segment's label, `null` while nothing is selected.
32
+
33
+ ### `select(label: string): Promise<void>`
34
+
35
+ Clicks the segment with this label, as a user would. Throws for an unknown label, and for a
36
+ disabled segment or control (a user's click would do nothing).
37
+
38
+ | Parameter | Type | Description |
39
+ | --------- | -------- | -------------------- |
40
+ | `label` | `string` | The segment's label. |
41
+
42
+ ### `isDisabled(): Promise<boolean>`
43
+
44
+ Whether the control is disabled: every segment is.
45
+
46
+ ### `getErrorText(): Promise<string>`
47
+
48
+ The error text under the track.
@@ -0,0 +1,29 @@
1
+ # BfSegmentedSize
2
+
3
+ Former name of the shared size scale for segmented controls, kept until 1.0.0
4
+
5
+ Type from `@bitforgehq/ui` · since 0.1.0
6
+
7
+ **Deprecated** 0.3.0 use BfSize; removed in 1.0.0
8
+
9
+ The height step of a `bf-segmented`; the same scale as every sized widget.
10
+
11
+ ```ts
12
+ import { type BfSegmentedSize } from '@bitforgehq/ui';
13
+ ```
14
+
15
+ ## Signature
16
+
17
+ ```ts
18
+ type BfSegmentedSize = BfSize
19
+ ```
20
+
21
+ ## Values
22
+
23
+ - `sm`
24
+ - `md`
25
+ - `lg`
26
+
27
+ ## Uses
28
+
29
+ - [BfSize](bf-size.md)
@@ -0,0 +1,70 @@
1
+ # BfSelectHarness
2
+
3
+ Test harness for the select: reads its label and options and picks one
4
+
5
+ Class from `@bitforgehq/ui/testing` · since 0.3.0
6
+
7
+ Harness for `bf-select`. It works by option label, so a test never needs the native option
8
+ values (an object option's native value is its index).
9
+
10
+ ```ts
11
+ import { BfSelectHarness } from '@bitforgehq/ui/testing';
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```ts
17
+ class BfSelectHarness extends ComponentHarness
18
+ ```
19
+
20
+ ## Methods
21
+
22
+ ### `getLabel(): Promise<string>`
23
+
24
+ The visible label without the required mark, else the `aria-label`.
25
+
26
+ ### `getValueLabel(): Promise<string>`
27
+
28
+ The selected option's label, `''` while nothing is selected.
29
+
30
+ ### `getOptionLabels(): Promise<string[]>`
31
+
32
+ The labels of the options, in order, without the placeholder.
33
+
34
+ ### `selectOption(label: string): Promise<void>`
35
+
36
+ Chooses the option with this label, as a user would: the select's `value` becomes that
37
+ option's value. Throws, leaving the value as it is, for an unknown or disabled option and
38
+ while the select itself is disabled.
39
+
40
+ | Parameter | Type | Description |
41
+ | --------- | -------- | ------------------- |
42
+ | `label` | `string` | The option's label. |
43
+
44
+ ### `isDisabled(): Promise<boolean>`
45
+
46
+ Whether the select is disabled.
47
+
48
+ ### `isReadonly(): Promise<boolean>`
49
+
50
+ Whether the select is read-only (`aria-readonly`).
51
+
52
+ ### `isRequired(): Promise<boolean>`
53
+
54
+ Whether the select is required.
55
+
56
+ ### `getErrorText(): Promise<string>`
57
+
58
+ The error text under the select (an explicit message, or the first form error once touched).
59
+
60
+ ### `getHelpText(): Promise<string>`
61
+
62
+ The help text under the select; it is hidden while an error shows.
63
+
64
+ ### `focus(): Promise<void>`
65
+
66
+ Focuses the native select.
67
+
68
+ ### `blur(): Promise<void>`
69
+
70
+ Blurs the native select, which marks a bound form field touched.
@@ -0,0 +1,29 @@
1
+ # BfSelectOption
2
+
3
+ One choice of a select with its value, its label and a disabled flag
4
+
5
+ Interface from `@bitforgehq/ui` · since 0.1.0
6
+
7
+ One choice of `bf-select`; `value` is any type (a string by default).
8
+
9
+ ```ts
10
+ import { type BfSelectOption } from '@bitforgehq/ui';
11
+ ```
12
+
13
+ ## Signature
14
+
15
+ ```ts
16
+ interface BfSelectOption<T = string>
17
+ ```
18
+
19
+ ## Properties
20
+
21
+ | Name | Type | Default | Description |
22
+ | ---------- | --------- | -------- | ---------------------------------------------------------------- |
23
+ | `value` | `T` | required | The value the select's `value` takes when this option is chosen. |
24
+ | `label` | `string` | required | The text of the native `option`. |
25
+ | `disabled` | `boolean` | | Whether this option cannot be chosen. |
26
+
27
+ ## Used by
28
+
29
+ - [bf-select](../components/select.md)