@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.
- package/CHANGELOG.md +3665 -0
- package/LICENSE +21 -0
- package/README.md +175 -0
- package/ai/MANIFEST.index.json +383 -0
- package/ai/MANIFEST.json +7528 -0
- package/ai/REFERENCE.index.json +1461 -0
- package/ai/REFERENCE.json +7213 -0
- package/ai/UI_GUIDE.md +1159 -0
- package/ai/components/action-bar.md +209 -0
- package/ai/components/action-sheet.md +526 -0
- package/ai/components/alert-dialog.md +509 -0
- package/ai/components/alert.md +376 -0
- package/ai/components/avatar.md +146 -0
- package/ai/components/back-button.md +286 -0
- package/ai/components/badge.md +171 -0
- package/ai/components/button.md +431 -0
- package/ai/components/card.md +303 -0
- package/ai/components/checkbox.md +418 -0
- package/ai/components/chip-group.md +205 -0
- package/ai/components/chip.md +300 -0
- package/ai/components/content.md +474 -0
- package/ai/components/desktop-toast.md +420 -0
- package/ai/components/dialog.md +962 -0
- package/ai/components/empty-state.md +146 -0
- package/ai/components/field.md +319 -0
- package/ai/components/header.md +809 -0
- package/ai/components/icon-button.md +221 -0
- package/ai/components/icon.md +176 -0
- package/ai/components/input.md +455 -0
- package/ai/components/list-item.md +326 -0
- package/ai/components/list.md +178 -0
- package/ai/components/menu-button.md +377 -0
- package/ai/components/menu.md +661 -0
- package/ai/components/modal.md +613 -0
- package/ai/components/number-input.md +423 -0
- package/ai/components/page.md +299 -0
- package/ai/components/progress.md +215 -0
- package/ai/components/radio-group.md +432 -0
- package/ai/components/refresher.md +377 -0
- package/ai/components/segmented.md +517 -0
- package/ai/components/select.md +510 -0
- package/ai/components/sheet.md +845 -0
- package/ai/components/spinner.md +171 -0
- package/ai/components/stack-outlet.md +661 -0
- package/ai/components/tab-bar.md +427 -0
- package/ai/components/tab.md +295 -0
- package/ai/components/tabs.md +408 -0
- package/ai/components/textarea.md +371 -0
- package/ai/components/toast.md +522 -0
- package/ai/components/toggle.md +387 -0
- package/ai/reference/bf-action-directive.md +21 -0
- package/ai/reference/bf-action-sheet-action-role.md +27 -0
- package/ai/reference/bf-action-sheet-action.md +28 -0
- package/ai/reference/bf-action-sheet-options.md +28 -0
- package/ai/reference/bf-action-sheet-service.md +33 -0
- package/ai/reference/bf-alert-dialog-button-role.md +27 -0
- package/ai/reference/bf-alert-dialog-button.md +27 -0
- package/ai/reference/bf-alert-dialog-options.md +29 -0
- package/ai/reference/bf-alert-dialog-service.md +34 -0
- package/ai/reference/bf-alert-variant.md +28 -0
- package/ai/reference/bf-autocapitalize.md +30 -0
- package/ai/reference/bf-avatar-size.md +27 -0
- package/ai/reference/bf-avatar-variant.md +28 -0
- package/ai/reference/bf-back-at-root.md +28 -0
- package/ai/reference/bf-back-button-service.md +40 -0
- package/ai/reference/bf-badge-variant.md +29 -0
- package/ai/reference/bf-button-size.md +29 -0
- package/ai/reference/bf-button-type.md +28 -0
- package/ai/reference/bf-button-variant.md +29 -0
- package/ai/reference/bf-card-padding.md +26 -0
- package/ai/reference/bf-card-variant.md +28 -0
- package/ai/reference/bf-chip-group-mode.md +27 -0
- package/ai/reference/bf-chip-variant.md +26 -0
- package/ai/reference/bf-compare-with.md +24 -0
- package/ai/reference/bf-component-overlay-ref.md +33 -0
- package/ai/reference/bf-confirm-button-role.md +26 -0
- package/ai/reference/bf-confirm-button.md +27 -0
- package/ai/reference/bf-confirm-options.md +31 -0
- package/ai/reference/bf-confirm-size.md +26 -0
- package/ai/reference/bf-content-scroll-event.md +21 -0
- package/ai/reference/bf-defaults-options.md +32 -0
- package/ai/reference/bf-defaults.md +28 -0
- package/ai/reference/bf-desktop-toast-config.md +28 -0
- package/ai/reference/bf-desktop-toast-harness.md +33 -0
- package/ai/reference/bf-desktop-toast-options.md +28 -0
- package/ai/reference/bf-desktop-toast-position.md +28 -0
- package/ai/reference/bf-desktop-toast-service.md +42 -0
- package/ai/reference/bf-dialog-config.md +44 -0
- package/ai/reference/bf-dialog-harness.md +52 -0
- package/ai/reference/bf-dialog-ref.md +44 -0
- package/ai/reference/bf-dialog-role.md +26 -0
- package/ai/reference/bf-dialog-service.md +55 -0
- package/ai/reference/bf-dialog-size.md +31 -0
- package/ai/reference/bf-dialog-template-context.md +32 -0
- package/ai/reference/bf-empty-state-heading-level.md +26 -0
- package/ai/reference/bf-enter-key-hint.md +31 -0
- package/ai/reference/bf-field-control-class.md +32 -0
- package/ai/reference/bf-field-control-state.md +28 -0
- package/ai/reference/bf-field-size.md +29 -0
- package/ai/reference/bf-haptics-impact-style.md +27 -0
- package/ai/reference/bf-haptics-notification-type.md +27 -0
- package/ai/reference/bf-haptics-service.md +41 -0
- package/ai/reference/bf-harness-filters.md +29 -0
- package/ai/reference/bf-horizontal-scroll-directive.md +129 -0
- package/ai/reference/bf-icon-button-variant.md +28 -0
- package/ai/reference/bf-icon-size.md +27 -0
- package/ai/reference/bf-input-autocapitalize.md +36 -0
- package/ai/reference/bf-input-enter-key-hint.md +38 -0
- package/ai/reference/bf-input-input-mode.md +38 -0
- package/ai/reference/bf-input-mode.md +32 -0
- package/ai/reference/bf-input-type.md +35 -0
- package/ai/reference/bf-jsdom-shim-options.md +22 -0
- package/ai/reference/bf-keyboard-assist-behavior.md +26 -0
- package/ai/reference/bf-keyboard-assist-directive.md +185 -0
- package/ai/reference/bf-keyboard-phase.md +30 -0
- package/ai/reference/bf-keyboard-service.md +50 -0
- package/ai/reference/bf-labels-overrides.md +26 -0
- package/ai/reference/bf-labels.md +44 -0
- package/ai/reference/bf-menu-button-harness.md +40 -0
- package/ai/reference/bf-menu-button-variant.md +27 -0
- package/ai/reference/bf-menu-divider-directive.md +13 -0
- package/ai/reference/bf-menu-group-directive.md +14 -0
- package/ai/reference/bf-menu-harness.md +55 -0
- package/ai/reference/bf-menu-item-checkbox-directive.md +31 -0
- package/ai/reference/bf-menu-item-directive.md +31 -0
- package/ai/reference/bf-menu-item-harness.md +52 -0
- package/ai/reference/bf-menu-item-radio-directive.md +29 -0
- package/ai/reference/bf-menu-placement.md +29 -0
- package/ai/reference/bf-menu-trigger-directive.md +46 -0
- package/ai/reference/bf-modal-options.md +30 -0
- package/ai/reference/bf-modal-presentation.md +26 -0
- package/ai/reference/bf-modal-service.md +38 -0
- package/ai/reference/bf-nav-controller.md +59 -0
- package/ai/reference/bf-nav-direction.md +23 -0
- package/ai/reference/bf-nav-target.md +21 -0
- package/ai/reference/bf-number-input-mode.md +28 -0
- package/ai/reference/bf-number-input-step.md +25 -0
- package/ai/reference/bf-overlay-auto-focus.md +29 -0
- package/ai/reference/bf-overlay-controller.md +22 -0
- package/ai/reference/bf-overlay-host.md +36 -0
- package/ai/reference/bf-overlay-options.md +53 -0
- package/ai/reference/bf-overlay-position.md +30 -0
- package/ai/reference/bf-overlay-ref.md +53 -0
- package/ai/reference/bf-overlay-role.md +27 -0
- package/ai/reference/bf-overlay-service.md +53 -0
- package/ai/reference/bf-overlay-stack-options.md +24 -0
- package/ai/reference/bf-overlay-stack.md +81 -0
- package/ai/reference/bf-overlay-template-context.md +24 -0
- package/ai/reference/bf-overscroll-stretch-directive.md +163 -0
- package/ai/reference/bf-page-context.md +24 -0
- package/ai/reference/bf-platform-service.md +53 -0
- package/ai/reference/bf-platform.md +28 -0
- package/ai/reference/bf-progress-size.md +26 -0
- package/ai/reference/bf-progress-tone.md +28 -0
- package/ai/reference/bf-radio-group-harness.md +49 -0
- package/ai/reference/bf-radio-group-orientation.md +26 -0
- package/ai/reference/bf-radio-option.md +30 -0
- package/ai/reference/bf-refresher-refresh-event.md +22 -0
- package/ai/reference/bf-segment-option.md +29 -0
- package/ai/reference/bf-segmented-harness.md +48 -0
- package/ai/reference/bf-segmented-size.md +29 -0
- package/ai/reference/bf-select-harness.md +70 -0
- package/ai/reference/bf-select-option.md +29 -0
- package/ai/reference/bf-sheet-auto-focus.md +29 -0
- package/ai/reference/bf-sheet-options.md +32 -0
- package/ai/reference/bf-sheet-ref.md +45 -0
- package/ai/reference/bf-sheet-service.md +34 -0
- package/ai/reference/bf-shell-config-mode.md +28 -0
- package/ai/reference/bf-shell-config.md +38 -0
- package/ai/reference/bf-shell-dynamic-type-limit.md +21 -0
- package/ai/reference/bf-shell-dynamic-type.md +25 -0
- package/ai/reference/bf-shell-mode.md +28 -0
- package/ai/reference/bf-shell-testing-options.md +26 -0
- package/ai/reference/bf-size.md +45 -0
- package/ai/reference/bf-spinner-size.md +27 -0
- package/ai/reference/bf-stack-change.md +22 -0
- package/ai/reference/bf-stack-reuse-strategy.md +32 -0
- package/ai/reference/bf-stack-transition-event.md +26 -0
- package/ai/reference/bf-stack-transition.md +26 -0
- package/ai/reference/bf-stacked-overlay.md +23 -0
- package/ai/reference/bf-system-bars-style.md +38 -0
- package/ai/reference/bf-tab-bar-controller.md +51 -0
- package/ai/reference/bf-tab-bar-host.md +52 -0
- package/ai/reference/bf-tab-context.md +32 -0
- package/ai/reference/bf-tab-links.md +37 -0
- package/ai/reference/bf-testing-options.md +27 -0
- package/ai/reference/bf-text-scale-service.md +35 -0
- package/ai/reference/bf-theme.md +27 -0
- package/ai/reference/bf-toast-action.md +25 -0
- package/ai/reference/bf-toast-controller.md +17 -0
- package/ai/reference/bf-toast-dismiss-reason.md +29 -0
- package/ai/reference/bf-toast-options.md +29 -0
- package/ai/reference/bf-toast-position.md +26 -0
- package/ai/reference/bf-toast-ref.md +41 -0
- package/ai/reference/bf-toast-service.md +39 -0
- package/ai/reference/bf-toggle-label-position.md +26 -0
- package/ai/reference/bf-transition-kind.md +28 -0
- package/ai/reference/bf-validation-message.md +31 -0
- package/ai/reference/bf-validation-messages.md +33 -0
- package/ai/reference/bf-view-event.md +28 -0
- package/ai/reference/bf-view-lifecycle.md +41 -0
- package/ai/reference/bf-view-state.md +28 -0
- package/ai/reference/bf_default_labels.md +21 -0
- package/ai/reference/bf_default_values.md +21 -0
- package/ai/reference/bf_defaults.md +21 -0
- package/ai/reference/bf_desktop_toast_defaults.md +21 -0
- package/ai/reference/bf_dialog_data.md +17 -0
- package/ai/reference/bf_labels.md +21 -0
- package/ai/reference/bf_overlay_data.md +19 -0
- package/ai/reference/bf_overlay_host.md +21 -0
- package/ai/reference/bf_sheet_default_snap_points.md +17 -0
- package/ai/reference/bf_shell_config.md +21 -0
- package/ai/reference/bf_shell_defaults.md +21 -0
- package/ai/reference/bf_tab_bar.md +21 -0
- package/ai/reference/bf_tab_bar_controller.md +21 -0
- package/ai/reference/bf_tab_context.md +21 -0
- package/ai/reference/bf_tab_links.md +21 -0
- package/ai/reference/bf_theme_storage.md +19 -0
- package/ai/reference/create-transition.md +36 -0
- package/ai/reference/duration_fast.md +17 -0
- package/ai/reference/duration_md.md +17 -0
- package/ai/reference/duration_overlay.md +17 -0
- package/ai/reference/duration_push.md +17 -0
- package/ai/reference/fade-down.md +26 -0
- package/ai/reference/fade-in.md +25 -0
- package/ai/reference/fade-out.md +25 -0
- package/ai/reference/fade-up.md +26 -0
- package/ai/reference/inject-shell-mode.md +23 -0
- package/ai/reference/install-bf-jsdom-shims.md +31 -0
- package/ai/reference/ios_duration.md +17 -0
- package/ai/reference/ios_easing.md +17 -0
- package/ai/reference/is-text-entry.md +25 -0
- package/ai/reference/max_complete_ms.md +17 -0
- package/ai/reference/md-transition.md +31 -0
- package/ai/reference/md_duration.md +17 -0
- package/ai/reference/md_easing.md +17 -0
- package/ai/reference/overlay_duration.md +21 -0
- package/ai/reference/overlay_easing.md +19 -0
- package/ai/reference/overlay_reduced_duration.md +17 -0
- package/ai/reference/pop-frames-at.md +25 -0
- package/ai/reference/prefers-reduced-motion.md +25 -0
- package/ai/reference/provide-bf-defaults.md +33 -0
- package/ai/reference/provide-bf-desktop-toast.md +28 -0
- package/ai/reference/provide-bf-labels.md +38 -0
- package/ai/reference/provide-bf-shell-testing.md +34 -0
- package/ai/reference/provide-bf-shell.md +41 -0
- package/ai/reference/provide-bf-testing.md +33 -0
- package/ai/reference/reduced-transition.md +28 -0
- package/ai/reference/reduced_duration.md +17 -0
- package/ai/reference/resolve-shell-mode.md +33 -0
- package/ai/reference/scale-in.md +25 -0
- package/ai/reference/settle-duration.md +25 -0
- package/ai/reference/settle-pop.md +33 -0
- package/ai/reference/settle_easing.md +17 -0
- package/ai/reference/should-complete-pop.md +26 -0
- package/ai/reference/slide-down.md +26 -0
- package/ai/reference/slide-up.md +26 -0
- package/ai/reference/with-bf-shell-routing.md +19 -0
- package/bin/bf-ui.js +81 -0
- package/fesm2022/bitforgehq-ui-icons.mjs +230 -0
- package/fesm2022/bitforgehq-ui-icons.mjs.map +1 -0
- package/fesm2022/bitforgehq-ui-mobile.mjs +5530 -0
- package/fesm2022/bitforgehq-ui-mobile.mjs.map +1 -0
- package/fesm2022/bitforgehq-ui-number-input.mjs +680 -0
- package/fesm2022/bitforgehq-ui-number-input.mjs.map +1 -0
- package/fesm2022/bitforgehq-ui-overlay.mjs +2675 -0
- package/fesm2022/bitforgehq-ui-overlay.mjs.map +1 -0
- package/fesm2022/bitforgehq-ui-testing.mjs +402 -0
- package/fesm2022/bitforgehq-ui-testing.mjs.map +1 -0
- package/fesm2022/bitforgehq-ui.mjs +7765 -0
- package/fesm2022/bitforgehq-ui.mjs.map +1 -0
- package/llms-full.txt +25394 -0
- package/llms.txt +329 -0
- package/package.json +94 -0
- package/theme.css +253 -0
- package/types/bitforgehq-ui-icons.d.ts +50 -0
- package/types/bitforgehq-ui-mobile.d.ts +2914 -0
- package/types/bitforgehq-ui-number-input.d.ts +282 -0
- package/types/bitforgehq-ui-overlay.d.ts +1514 -0
- package/types/bitforgehq-ui-testing.d.ts +495 -0
- package/types/bitforgehq-ui.d.ts +3499 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# bf-tab
|
|
2
|
+
|
|
3
|
+
One tab bar destination with an icon, a label and an optional count badge
|
|
4
|
+
|
|
5
|
+
`BfTabComponent` from `@bitforgehq/ui` · Navigation · since 0.1.0
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Component, signal } from '@angular/core';
|
|
11
|
+
import { BfTabBarComponent, BfTabComponent } from '@bitforgehq/ui';
|
|
12
|
+
import { BfIconComponent } from '@bitforgehq/ui/icons';
|
|
13
|
+
import { Inbox, Sun } from 'lucide';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The bf-tab overview.
|
|
17
|
+
*
|
|
18
|
+
* Live demo of `bf-tab`: two tabs inside a `bf-tab-bar`, one with a badge; click to switch.
|
|
19
|
+
*/
|
|
20
|
+
@Component({
|
|
21
|
+
selector: 'app-example-tab-overview',
|
|
22
|
+
imports: [BfTabBarComponent, BfTabComponent, BfIconComponent],
|
|
23
|
+
template: `
|
|
24
|
+
<bf-tab-bar [(active)]="active" [floating]="false" label="Sections">
|
|
25
|
+
<bf-tab id="today" label="Today"><bf-icon [icon]="sun" /></bf-tab>
|
|
26
|
+
<bf-tab id="inbox" label="Inbox" [badge]="2"><bf-icon [icon]="inbox" /></bf-tab>
|
|
27
|
+
</bf-tab-bar>
|
|
28
|
+
<p data-status aria-live="polite" class="text-caption text-text-muted mt-3">
|
|
29
|
+
Active tab: {{ active() }}
|
|
30
|
+
</p>
|
|
31
|
+
`,
|
|
32
|
+
})
|
|
33
|
+
export class TabOverviewExampleComponent {
|
|
34
|
+
readonly active = signal('today');
|
|
35
|
+
readonly sun = Sun;
|
|
36
|
+
readonly inbox = Inbox;
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Overview
|
|
41
|
+
|
|
42
|
+
One destination inside `bf-tab-bar`: icon in the default slot, `label` under it, optional count
|
|
43
|
+
`badge`. A `button role="tab"` in a standalone bar; inside `bf-tabs`, a link to the tab's URL
|
|
44
|
+
with `aria-current` while active: `page` on the tab's root page, `true` on a child page of it
|
|
45
|
+
(the current section, not the current page).
|
|
46
|
+
|
|
47
|
+
One destination of a [`bf-tab-bar`](https://bitforge-ui.web.app/components/tab-bar): an icon in the default slot with a `label` underneath. A `bf-tab` lives only inside a bar, which owns the selection (`active`), the keyboard navigation and the floating layout; this page covers what a single tab adds: its id, its badge and its disabled state.
|
|
48
|
+
|
|
49
|
+
## When to use
|
|
50
|
+
|
|
51
|
+
Use `bf-tab` for each destination of a [bf-tab-bar](https://bitforge-ui.web.app/components/tab-bar), and only there. Use [bf-segmented](https://bitforge-ui.web.app/components/segmented) instead for options that switch a view inside a page, and [bf-button](https://bitforge-ui.web.app/components/button) for an action.
|
|
52
|
+
|
|
53
|
+
## Basic usage
|
|
54
|
+
|
|
55
|
+
Give every tab an `id` (the selection key the bar's `active` holds and `changed` emits) and a short `label`, and put a `bf-icon` in its default slot. The `id` is not a host DOM id: the host drops its own `id` attribute, and the id lands once, on the tab's inner `<button>` (or `<a>` inside `bf-tabs`).
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { Component, signal } from '@angular/core';
|
|
59
|
+
import { BfTabBarComponent, BfTabComponent } from '@bitforgehq/ui';
|
|
60
|
+
import { BfIconComponent } from '@bitforgehq/ui/icons';
|
|
61
|
+
import { FileText, FolderOpen, Users } from 'lucide';
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Tabs with an icon and a label.
|
|
65
|
+
*
|
|
66
|
+
* Each `bf-tab` is one destination: its `id` is the selection key the bar's `active` holds.
|
|
67
|
+
*/
|
|
68
|
+
@Component({
|
|
69
|
+
selector: 'app-example-tab-basic',
|
|
70
|
+
imports: [BfTabBarComponent, BfTabComponent, BfIconComponent],
|
|
71
|
+
template: `
|
|
72
|
+
<div class="flex flex-col items-center gap-3">
|
|
73
|
+
<bf-tab-bar [(active)]="active" [floating]="false" label="Workspace">
|
|
74
|
+
<bf-tab id="notes" label="Notes"><bf-icon [icon]="fileText" /></bf-tab>
|
|
75
|
+
<bf-tab id="files" label="Files"><bf-icon [icon]="folderOpen" /></bf-tab>
|
|
76
|
+
<bf-tab id="people" label="People"><bf-icon [icon]="users" /></bf-tab>
|
|
77
|
+
</bf-tab-bar>
|
|
78
|
+
<p class="text-caption text-text-muted">active: {{ active() }}</p>
|
|
79
|
+
</div>
|
|
80
|
+
`,
|
|
81
|
+
})
|
|
82
|
+
export class TabBasicExampleComponent {
|
|
83
|
+
protected readonly fileText = FileText;
|
|
84
|
+
protected readonly folderOpen = FolderOpen;
|
|
85
|
+
protected readonly users = Users;
|
|
86
|
+
protected readonly active = signal('notes');
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Badges
|
|
91
|
+
|
|
92
|
+
Give a tab a `badge` for an unread or pending count, or a short text. The badge sits at the inline end of the icon (its left under `dir="rtl"`). A number is announced through `provideBfLabels()`'s `tabBadge(n)` ("3 new"); a string is announced as written.
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { Component, signal } from '@angular/core';
|
|
96
|
+
import { BfTabBarComponent, BfTabComponent } from '@bitforgehq/ui';
|
|
97
|
+
import { BfIconComponent } from '@bitforgehq/ui/icons';
|
|
98
|
+
import { Bell, MessageCircle } from 'lucide';
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Tabs with badges.
|
|
102
|
+
*
|
|
103
|
+
* A number badge is announced as "Messages, 3 new"; a text badge is announced as written.
|
|
104
|
+
*/
|
|
105
|
+
@Component({
|
|
106
|
+
selector: 'app-example-tab-badges',
|
|
107
|
+
imports: [BfTabBarComponent, BfTabComponent, BfIconComponent],
|
|
108
|
+
template: `
|
|
109
|
+
<bf-tab-bar [(active)]="active" [floating]="false" label="Updates">
|
|
110
|
+
<bf-tab id="messages" label="Messages" [badge]="3"><bf-icon [icon]="messageCircle" /></bf-tab>
|
|
111
|
+
<bf-tab id="alerts" label="Alerts" badge="!"><bf-icon [icon]="bell" /></bf-tab>
|
|
112
|
+
</bf-tab-bar>
|
|
113
|
+
`,
|
|
114
|
+
})
|
|
115
|
+
export class TabBadgesExampleComponent {
|
|
116
|
+
protected readonly messageCircle = MessageCircle;
|
|
117
|
+
protected readonly bell = Bell;
|
|
118
|
+
protected readonly active = signal('messages');
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Disabled
|
|
123
|
+
|
|
124
|
+
`disabled` greys the tab out and takes it out of the keyboard navigation; it cannot be clicked. Inside `bf-tabs` a disabled tab is a link without an `href`.
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import { Component, signal } from '@angular/core';
|
|
128
|
+
import { BfTabBarComponent, BfTabComponent } from '@bitforgehq/ui';
|
|
129
|
+
import { BfIconComponent } from '@bitforgehq/ui/icons';
|
|
130
|
+
import { Archive, PenLine } from 'lucide';
|
|
131
|
+
|
|
132
|
+
/** A disabled tab: skipped by the arrow keys and not clickable. */
|
|
133
|
+
@Component({
|
|
134
|
+
selector: 'app-example-tab-disabled',
|
|
135
|
+
imports: [BfTabBarComponent, BfTabComponent, BfIconComponent],
|
|
136
|
+
template: `
|
|
137
|
+
<bf-tab-bar [(active)]="active" [floating]="false" label="Mail">
|
|
138
|
+
<bf-tab id="drafts" label="Drafts"><bf-icon [icon]="penLine" /></bf-tab>
|
|
139
|
+
<bf-tab id="archive" label="Archive" [disabled]="true"><bf-icon [icon]="archive" /></bf-tab>
|
|
140
|
+
</bf-tab-bar>
|
|
141
|
+
`,
|
|
142
|
+
})
|
|
143
|
+
export class TabDisabledExampleComponent {
|
|
144
|
+
protected readonly penLine = PenLine;
|
|
145
|
+
protected readonly archive = Archive;
|
|
146
|
+
protected readonly active = signal('drafts');
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Desktop
|
|
151
|
+
|
|
152
|
+
A tab lives in a phone tab bar; see the [bf-tab-bar](https://bitforge-ui.web.app/components/tab-bar) page for what to use on desktop. Under a mouse an inactive tab takes a `surface-muted` fill and a `text` icon on hover, the active capsule `primary-soft-hover`, with the pointer cursor; a disabled tab shows `not-allowed`. The focus ring shows on keyboard focus only.
|
|
153
|
+
|
|
154
|
+
## Theming
|
|
155
|
+
|
|
156
|
+
- Active tab capsule: `primary-soft` background, `primary-strong` icon/label and a 1.5 px inset
|
|
157
|
+
`primary-strong` outline, so the active tab does not rest on the fill alone. Inactive: `text-muted`.
|
|
158
|
+
- Hover (pointer cursor): the active capsule goes to `primary-soft-hover`, an inactive one takes a
|
|
159
|
+
`surface-muted` fill and `text` icon.
|
|
160
|
+
- Pressed: the capsule takes `primary-soft-pressed` (an inactive one with a `text` icon); none
|
|
161
|
+
while disabled.
|
|
162
|
+
- Disabled tab (`disabled` button, or `aria-disabled` link inside `bf-tabs`): `surface-sunken`
|
|
163
|
+
capsule, `text-disabled` icon and label (never opacity).
|
|
164
|
+
- A label longer than the tab's width wraps to at most two lines; a long word is hyphenated where the page's `lang` allows it (`hyphens-auto`), else broken where it must be.
|
|
165
|
+
- Label: `text-nano` (11/14 px), capped at 200 % (22/28 px, `min(var(--text-nano), 22px)`, in px
|
|
166
|
+
because iOS Dynamic Type scales the root); the capsule (30 × 52 px), its icon, the badge
|
|
167
|
+
(18 px, its count capped at 13 px), the padding and the gaps are px, so they keep their size at
|
|
168
|
+
every text size. The label
|
|
169
|
+
never clips vertically: the bar grows with a two-line label. At compact heights
|
|
170
|
+
(`(max-height: 500px)`, phone landscape) the icon and the label sit side by side
|
|
171
|
+
(`flex-row gap-1.5`).
|
|
172
|
+
- Badge: `primary` background, `on-primary` text; always a circle (`rounded-full`).
|
|
173
|
+
- Shape (tab and capsule): `rounded-control` (`--radius-control`, `9999px` by default).
|
|
174
|
+
- Focus ring: `ring`.
|
|
175
|
+
|
|
176
|
+
## Accessibility
|
|
177
|
+
|
|
178
|
+
In a standalone bar a tab is a native `<button role="tab">` with `aria-selected`, one of a
|
|
179
|
+
roving-`tabindex` tablist; inside `bf-tabs` it is an `<a href>` link to the tab's root URL, with
|
|
180
|
+
`aria-current` while active. The bar decides which form it takes; the
|
|
181
|
+
[`bf-tab-bar` page](https://bitforge-ui.web.app/components/tab-bar#accessibility) describes both,
|
|
182
|
+
with their keyboard behaviour.
|
|
183
|
+
|
|
184
|
+
The visible `label` is the tab's name. With a `badge`, the badge text is `aria-hidden` and the
|
|
185
|
+
name becomes the label, a comma and the announcement ("Inbox, 3 new", one string with no pause
|
|
186
|
+
before the comma), so it still starts with the visible label. A `disabled` tab is native-disabled
|
|
187
|
+
(a button) or `aria-disabled="true"` without an `href` (a link), so it is skipped by Tab and inert.
|
|
188
|
+
The active capsule stays visible under `forced-colors` (`Highlight`/`HighlightText`).
|
|
189
|
+
|
|
190
|
+
### Keyboard
|
|
191
|
+
|
|
192
|
+
The bar owns the tab stop and the arrow keys; its [Accessibility section](https://bitforge-ui.web.app/components/tab-bar#keyboard) has the full table.
|
|
193
|
+
|
|
194
|
+
| Key | Action |
|
|
195
|
+
| ----------------------------------- | -------------------------------------------------------------------------------------- |
|
|
196
|
+
| <kbd>Enter</kbd> / <kbd>Space</kbd> | Standalone bar: selects the focused tab; on the active tab, the bar emits `reselected` |
|
|
197
|
+
| <kbd>Enter</kbd> | Inside `bf-tabs`: follows the tab's link |
|
|
198
|
+
|
|
199
|
+
## Inputs
|
|
200
|
+
|
|
201
|
+
| Name | Type | Default | Description |
|
|
202
|
+
| ---------- | -------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
203
|
+
| `id` | `string` | required | Stable identifier; matches `bf-tab-bar`'s `active` when this tab is selected. It is a selection key only, never reflected as the DOM `id` of more than the inner `<button>` (or `<a>` inside `bf-tabs`). |
|
|
204
|
+
| `label` | `string` | required | Visible label under the icon. |
|
|
205
|
+
| `badge` | `string \| number \| null` | `null` | Optional count shown as a badge on the icon capsule; announced to screen readers as part of the tab's accessible name (`aria-label` "{label}, {announcement}", with `provideBfLabels()`'s `tabBadge(n)`, `"{n} new"`, for a number, the string as-is otherwise) since the badge itself is `aria-hidden`. |
|
|
206
|
+
| `disabled` | `boolean` | `false` | Disables the tab: skipped by keyboard navigation, cannot be clicked. |
|
|
207
|
+
|
|
208
|
+
## Slots
|
|
209
|
+
|
|
210
|
+
- `default`: The tab icon, a `bf-icon` above the label.
|
|
211
|
+
|
|
212
|
+
## Methods
|
|
213
|
+
|
|
214
|
+
### `focus(): void`
|
|
215
|
+
|
|
216
|
+
Moves keyboard focus to this tab's button (or link); called by `bf-tab-bar` after arrow-key
|
|
217
|
+
selection.
|
|
218
|
+
|
|
219
|
+
## Notes
|
|
220
|
+
|
|
221
|
+
### Do
|
|
222
|
+
|
|
223
|
+
- Give each tab a short, one-word label ("Benachrichtigungen" wraps in a quarter-width tab).
|
|
224
|
+
- Keep ids stable and meaningful (`today`, `inbox`): they are what `active` stores and routes map to.
|
|
225
|
+
|
|
226
|
+
### Don't
|
|
227
|
+
|
|
228
|
+
- Don't use a `bf-tab` outside a `bf-tab-bar`.
|
|
229
|
+
- Don't rely on the badge alone for important information; it is a count, not a message.
|
|
230
|
+
|
|
231
|
+
## Migration notes
|
|
232
|
+
|
|
233
|
+
### 0.3.0
|
|
234
|
+
|
|
235
|
+
**Breaking:** (ARIA contract) inside `bf-tabs` a tab is `<a href>` with `aria-current` while
|
|
236
|
+
active: `page` on the tab's root page, `true` on a child page of it (no `role="tab"` or
|
|
237
|
+
`aria-selected`); a disabled one is `<a role="link" aria-disabled="true">` without `href`. A plain
|
|
238
|
+
primary click selects the tab through the bar (default prevented); Ctrl/Cmd, Shift, Alt and middle
|
|
239
|
+
clicks open the link in a new tab or window. The link's underline is removed with an important
|
|
240
|
+
utility (`no-underline!`), so an unlayered global link rule cannot underline it. See Migration 11.
|
|
241
|
+
|
|
242
|
+
**Behaviour:** a badged tab is named by `aria-label` = label, comma, announcement ("Projects, 3
|
|
243
|
+
new"; was "Projects , 3 new", with a pause, from a visually hidden span that browsers joined with a
|
|
244
|
+
space), in both forms; the `sr-only` announcement span is gone. Without a badge the visible label
|
|
245
|
+
is the name, as before.
|
|
246
|
+
|
|
247
|
+
**Behaviour:** the badge is placed with a logical inset (`-end-2`), so it sits at the icon's
|
|
248
|
+
inline end under `dir="rtl"`.
|
|
249
|
+
|
|
250
|
+
**Behaviour:** a numeric `badge` is announced through `provideBfLabels()`'s `tabBadge(count)`
|
|
251
|
+
(`"{n} new"` by default, now translatable); a string badge is announced as given.
|
|
252
|
+
|
|
253
|
+
**Behaviour:** the active capsule carries a 1.5 px inset `primary-strong` outline (≥ 3:1 on its
|
|
254
|
+
`primary-soft` fill and the bar), so the active tab no longer rests on a fill 1.23:1 from the bar;
|
|
255
|
+
a disabled active capsule is outlined in `text-disabled`. The tab and its capsule use
|
|
256
|
+
`rounded-control` (`--radius-control`); the count badge stays a circle.
|
|
257
|
+
|
|
258
|
+
**Docs:** `bf-tab` has a page of its own (`tab-bar/tab.docs.md`): its id, its badges (moved from
|
|
259
|
+
the `bf-tab-bar` page) and a disabled tab, with the tab's own theming and accessibility; the
|
|
260
|
+
`bf-tab-bar` page links to it.
|
|
261
|
+
|
|
262
|
+
JSDoc of `tab.component.ts` for the API reference: `@slot` docs for `default`; template handlers and
|
|
263
|
+
framework hooks marked `@internal`, so the reference leaves them out. No behaviour change.
|
|
264
|
+
|
|
265
|
+
**Behaviour:** a pressed state (F-045): the capsule of an enabled tab takes `primary-soft-pressed` (an inactive one with the `text` icon) while the tab is held down. None while disabled; under forced colours the system colours win.
|
|
266
|
+
|
|
267
|
+
**Behaviour:** large text (F-051): the label's size and line height are capped at 200 %
|
|
268
|
+
(`min(var(--text-nano), 22px)`, `min(var(--text-nano--line-height), 28px)`, in px because iOS
|
|
269
|
+
Dynamic Type scales the root); it still wraps to at most two lines and never clips vertically. The
|
|
270
|
+
tab has 4 px of vertical padding, so a grown tab keeps off the bar's edge. The capsule (30 × 52
|
|
271
|
+
px), the badge (18 px, its count capped at 13 px), the padding and the gaps are px, so they keep
|
|
272
|
+
their size at every text size. The label hyphenates a long word where the engine has
|
|
273
|
+
hyphenation for the page's `lang` (`hyphens-auto wrap-break-word`, was `wrap-anywhere`), and
|
|
274
|
+
otherwise still breaks it rather than overflowing (WKWebView on the iOS 18 simulator does not
|
|
275
|
+
hyphenate "Projects", so it still reads "Projec/ts" at AX5). At
|
|
276
|
+
compact heights (`(max-height: 500px)`, F-054) the icon and the label sit side by side
|
|
277
|
+
(`flex-row gap-[6px]`).
|
|
278
|
+
|
|
279
|
+
### 0.2.0
|
|
280
|
+
|
|
281
|
+
The label is `text-nano` (11/14; the line was 16.5 px). Dropped the `[&>svg]:h-5 [&>svg]:w-5`
|
|
282
|
+
selector, which never matched (icons render inside the `bf-icon` host). A disabled tab uses tokens
|
|
283
|
+
instead of `opacity-40`: `surface-sunken` capsule, `text-disabled` icon and label. The tab can
|
|
284
|
+
shrink (`min-w-0`) and its label is capped at `max-w-full px-1` (it wraps, see "Changed" below), so
|
|
285
|
+
a long label no longer overflows its quarter of the bar.
|
|
286
|
+
|
|
287
|
+
Fixed: the tab shows a pointer cursor and its capsule a hover (`primary-soft-hover` when active,
|
|
288
|
+
`surface-muted` fill and `text` icon when inactive); a disabled tab keeps its sunken capsule.
|
|
289
|
+
|
|
290
|
+
Changed: a long label wraps to at most two lines (`line-clamp-2 wrap-anywhere text-center`) instead
|
|
291
|
+
of truncating to one, so "Benachrichtigungen" stays readable in a quarter-width tab.
|
|
292
|
+
|
|
293
|
+
### 0.1.0
|
|
294
|
+
|
|
295
|
+
New `bf-tab`: one destination inside `bf-tab-bar` — an icon in the default slot, `label` under it, and an optional `badge` count. `id` and `label` are required; `disabled` removes it from keyboard navigation and blocks clicks. Renders a native `<button role="tab">` with `aria-selected` and a roving `tabindex` driven by the bar's `tabStop`; the active tab's icon sits on a `primary-soft` capsule (`forced-colors:bg-[Highlight]`) with a `primary-strong` label, inactive tabs are `text-muted`. The host no longer reflects `id` as a DOM attribute (`bf-tab id="today"` previously duplicated `id="today"` onto both the host and the inner `<button>`); the id now lands once, on the button. The badge is `aria-hidden`; a visually hidden `sr-only` span after the label announces it instead (`"{n} new"` for a numeric badge, the string as-is otherwise), so the tab's accessible name carries meaning instead of a bare number.
|