@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,300 @@
|
|
|
1
|
+
# bf-chip
|
|
2
|
+
|
|
3
|
+
Toggleable filter chip with a check mark when selected, in tonal or ink style
|
|
4
|
+
|
|
5
|
+
`BfChipComponent` from `@bitforgehq/ui` · Forms · since 0.1.0
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Component, computed, signal } from '@angular/core';
|
|
11
|
+
import { BfChipComponent } from '@bitforgehq/ui';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The bf-chip overview.
|
|
15
|
+
*
|
|
16
|
+
* Live demo of `bf-chip`: a tonal filter row with two selected, and a single-choice ink row; the selection is echoed underneath; then the sm, md and lg sizes in a row.
|
|
17
|
+
*/
|
|
18
|
+
@Component({
|
|
19
|
+
selector: 'app-example-chip-overview',
|
|
20
|
+
imports: [BfChipComponent],
|
|
21
|
+
template: `
|
|
22
|
+
<div class="flex flex-col gap-3">
|
|
23
|
+
<div class="flex flex-wrap gap-2">
|
|
24
|
+
<bf-chip [(selected)]="filterDesign">Design</bf-chip>
|
|
25
|
+
<bf-chip [(selected)]="filterDevelopment">Development</bf-chip>
|
|
26
|
+
<bf-chip [(selected)]="filterCopy">Copy</bf-chip>
|
|
27
|
+
<bf-chip [(selected)]="filterResearch">Research</bf-chip>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="flex flex-wrap gap-2">
|
|
30
|
+
@for (option of statusOptions; track option.value) {
|
|
31
|
+
<bf-chip
|
|
32
|
+
variant="ink"
|
|
33
|
+
[selected]="statusFilter() === option.value"
|
|
34
|
+
[deselectable]="false"
|
|
35
|
+
(changed)="setStatusFilter(option.value)"
|
|
36
|
+
>
|
|
37
|
+
{{ option.label }}
|
|
38
|
+
</bf-chip>
|
|
39
|
+
}
|
|
40
|
+
</div>
|
|
41
|
+
<p data-status aria-live="polite" class="text-caption text-text-muted">{{ status() }}</p>
|
|
42
|
+
<div data-sizes class="flex flex-wrap items-center gap-3">
|
|
43
|
+
<bf-chip size="sm">sm · 32 px</bf-chip>
|
|
44
|
+
<bf-chip>md · 40 px</bf-chip>
|
|
45
|
+
<bf-chip size="lg">lg · 48 px</bf-chip>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
`,
|
|
49
|
+
})
|
|
50
|
+
export class ChipOverviewExampleComponent {
|
|
51
|
+
readonly filterDesign = signal(true);
|
|
52
|
+
readonly filterDevelopment = signal(false);
|
|
53
|
+
readonly filterCopy = signal(true);
|
|
54
|
+
readonly filterResearch = signal(false);
|
|
55
|
+
|
|
56
|
+
readonly statusFilter = signal('all');
|
|
57
|
+
readonly statusOptions: { value: string; label: string }[] = [
|
|
58
|
+
{ value: 'all', label: 'All' },
|
|
59
|
+
{ value: 'open', label: 'Open' },
|
|
60
|
+
{ value: 'done', label: 'Done' },
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
readonly status = computed(() => {
|
|
64
|
+
const filters = [
|
|
65
|
+
this.filterDesign() ? 'Design' : '',
|
|
66
|
+
this.filterDevelopment() ? 'Development' : '',
|
|
67
|
+
this.filterCopy() ? 'Copy' : '',
|
|
68
|
+
this.filterResearch() ? 'Research' : '',
|
|
69
|
+
].filter(Boolean);
|
|
70
|
+
const status = this.statusOptions.find((o) => o.value === this.statusFilter())?.label ?? '';
|
|
71
|
+
return `Filters: ${filters.length > 0 ? filters.join(', ') : 'none'} · Status: ${status}`;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
setStatusFilter(value: string): void {
|
|
75
|
+
this.statusFilter.set(value);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Overview
|
|
81
|
+
|
|
82
|
+
Toggleable filter chip. Selected chips carry a check mark and a tint (`tonal`) or the ink
|
|
83
|
+
treatment used by mobile filter rows (`ink`). For a single-choice row, put the chips in a
|
|
84
|
+
`bf-chip-group`, which makes them a radio group.
|
|
85
|
+
|
|
86
|
+
Chips are toggles for filters and tags. A selected chip shows a check mark and a tint; on mobile filter rows the `ink` variant gives the stronger contrast the design uses.
|
|
87
|
+
|
|
88
|
+
## When to use
|
|
89
|
+
|
|
90
|
+
Use `bf-chip` for filters and tags the user toggles, alone or in a row: "Open", "Mine", "This week". Use [bf-chip-group](https://bitforge-ui.web.app/components/chip-group) around the chips of a single-choice row, [bf-segmented](https://bitforge-ui.web.app/components/segmented) instead when two to four choices switch a whole view, [bf-badge](https://bitforge-ui.web.app/components/badge) for a read-only status, and [bf-checkbox](https://bitforge-ui.web.app/components/checkbox) for choices in a form that is submitted later.
|
|
91
|
+
|
|
92
|
+
## Basic usage
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { Component, signal } from '@angular/core';
|
|
96
|
+
import { BfChipComponent } from '@bitforgehq/ui';
|
|
97
|
+
|
|
98
|
+
/** Two filter chips, each toggling its own filter. */
|
|
99
|
+
@Component({
|
|
100
|
+
selector: 'app-example-chip-basic',
|
|
101
|
+
imports: [BfChipComponent],
|
|
102
|
+
template: `
|
|
103
|
+
<div class="flex flex-wrap gap-2">
|
|
104
|
+
<bf-chip [(selected)]="design">Design</bf-chip>
|
|
105
|
+
<bf-chip [(selected)]="copy">Copy</bf-chip>
|
|
106
|
+
</div>
|
|
107
|
+
`,
|
|
108
|
+
})
|
|
109
|
+
export class ChipBasicExampleComponent {
|
|
110
|
+
protected readonly design = signal(true);
|
|
111
|
+
protected readonly copy = signal(false);
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Single-choice filter row
|
|
116
|
+
|
|
117
|
+
For a row where exactly one chip is selected, put the chips in a [bf-chip-group](https://bitforge-ui.web.app/components/chip-group): it gives them radio semantics ("radio, 1 of 3, selected"), one tab stop and arrow-key navigation, and holds the selected chip's `value`. A row without a group keeps working as before: drive `selected` from your state and react to `changed`, with `[deselectable]="false"` so clicking the already-selected chip does nothing instead of clearing the selection; each chip then announces as a separate toggle button.
|
|
118
|
+
|
|
119
|
+
`value` (any type, compared with `Object.is`) is what a chip stands for inside a `bf-chip-group`; outside one it is unused.
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { Component, signal } from '@angular/core';
|
|
123
|
+
import { BfChipComponent } from '@bitforgehq/ui';
|
|
124
|
+
|
|
125
|
+
type View = 'all' | 'open' | 'done';
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* A single-choice filter row.
|
|
129
|
+
*
|
|
130
|
+
* Exactly one chip is selected; `deselectable` false keeps the selected one from turning off.
|
|
131
|
+
*/
|
|
132
|
+
@Component({
|
|
133
|
+
selector: 'app-example-chip-single-choice',
|
|
134
|
+
imports: [BfChipComponent],
|
|
135
|
+
template: `
|
|
136
|
+
<div class="flex flex-wrap gap-2">
|
|
137
|
+
@for (option of options; track option.value) {
|
|
138
|
+
<bf-chip
|
|
139
|
+
variant="ink"
|
|
140
|
+
[selected]="view() === option.value"
|
|
141
|
+
[deselectable]="false"
|
|
142
|
+
(changed)="view.set(option.value)"
|
|
143
|
+
>{{ option.label }}</bf-chip
|
|
144
|
+
>
|
|
145
|
+
}
|
|
146
|
+
</div>
|
|
147
|
+
`,
|
|
148
|
+
})
|
|
149
|
+
export class ChipSingleChoiceExampleComponent {
|
|
150
|
+
protected readonly options: { value: View; label: string }[] = [
|
|
151
|
+
{ value: 'all', label: 'All' },
|
|
152
|
+
{ value: 'open', label: 'Open' },
|
|
153
|
+
{ value: 'done', label: 'Done' },
|
|
154
|
+
];
|
|
155
|
+
protected readonly view = signal<View>('all');
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Sizes
|
|
160
|
+
|
|
161
|
+
`sm` 32 px, `md` 40 px (default), `lg` 48 px — the `BfSize` scale of `bf-button` and the fields, so a filter row lines up with the search field beside it. Unset, `size` follows `provideBfDefaults()`'s `controlSize`, `md` by default (`provideBfDefaults({ size: 'lg' })` enlarges every control of a Capacitor app; `{ size: 'sm' }` in a component's `providers` makes a dense sub-tree). Under a fine pointer (mouse, trackpad) the visible box is the hit area (32 px and up, above the 24 px of WCAG 2.5.8), so dense rows never overlap; under a coarse pointer (touch) `sm` and `md` grow to a 44 px hit area through an invisible extension.
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
import { Component, signal } from '@angular/core';
|
|
165
|
+
import { BfChipComponent } from '@bitforgehq/ui';
|
|
166
|
+
|
|
167
|
+
/** The sm, md and lg chip sizes. */
|
|
168
|
+
@Component({
|
|
169
|
+
selector: 'app-example-chip-sizes',
|
|
170
|
+
imports: [BfChipComponent],
|
|
171
|
+
template: `
|
|
172
|
+
<div class="flex flex-wrap items-center gap-2">
|
|
173
|
+
<bf-chip size="sm" [(selected)]="design">Design</bf-chip>
|
|
174
|
+
<bf-chip [(selected)]="copy">Copy</bf-chip>
|
|
175
|
+
<bf-chip size="lg" [(selected)]="video">Video</bf-chip>
|
|
176
|
+
</div>
|
|
177
|
+
`,
|
|
178
|
+
})
|
|
179
|
+
export class ChipSizesExampleComponent {
|
|
180
|
+
protected readonly design = signal(true);
|
|
181
|
+
protected readonly copy = signal(false);
|
|
182
|
+
protected readonly video = signal(false);
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Desktop
|
|
187
|
+
|
|
188
|
+
Hover darkens the unselected border (`text-muted`) or the selected fill, with the pointer cursor; disabled shows `not-allowed`. Hover styles apply only on devices that can hover, so a tap never leaves one stuck. The focus ring shows on keyboard focus only. Under a fine pointer the pill is the hit area, so `sm` chips make a compact filter row beside an `sm` search field. Desktop density is the default `md` step; `provideBfDefaults({ size: 'sm' })`, or `{ size: 'sm' }` in a component's `providers`, makes a dense toolbar, table or sidebar ([density guide](https://bitforge-ui.web.app/density)).
|
|
189
|
+
|
|
190
|
+
## Theming
|
|
191
|
+
|
|
192
|
+
Consumes tokens by state, unselected then selected:
|
|
193
|
+
|
|
194
|
+
- Unselected: `surface` / `text` / `border-strong` (the control boundary, ≥ 3:1), hover border `text-muted`.
|
|
195
|
+
- Selected `tonal` (default): `primary-soft` / `primary-strong`, hover `primary-soft-hover`.
|
|
196
|
+
- Selected `ink`: `text` / `bg`, hover `text-secondary`.
|
|
197
|
+
- Pressed: unselected `surface-pressed`; selected `tonal` `primary-soft-pressed`; selected `ink` `text-secondary`. None while disabled.
|
|
198
|
+
- Cursor: `pointer` while enabled, `not-allowed` when disabled.
|
|
199
|
+
- Focus ring: `ring`. Disabled: `surface-sunken` / `text-disabled`, border turns transparent (never opacity).
|
|
200
|
+
- Shape: `rounded-control` (`--radius-control`, `9999px` by default, so a pill); override the token to move every pill control off the pill at once.
|
|
201
|
+
|
|
202
|
+
Icon (or check mark) and label sit 6 px apart, tighter than `bf-button`'s 8 px to keep the pill's proportions. A long label truncates with an ellipsis.
|
|
203
|
+
|
|
204
|
+
## Accessibility
|
|
205
|
+
|
|
206
|
+
Native `<button type="button">` with `aria-pressed` mirroring `selected`, so it announces as a toggle button (inside a `single` `bf-chip-group` it is `role="radio"` with `aria-checked` instead, and the group owns the tab stop and the arrow keys); the check mark is `aria-hidden` since the pressed state already carries the meaning. Keyboard: native button activation (Enter/Space). `disabled` sets the native attribute, which also removes the chip from the tab order.
|
|
207
|
+
|
|
208
|
+
### Keyboard
|
|
209
|
+
|
|
210
|
+
| Key | Action |
|
|
211
|
+
| ----------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
212
|
+
| <kbd>Tab</kbd> | Moves focus to the chip; a `disabled` one is skipped |
|
|
213
|
+
| <kbd>Enter</kbd> / <kbd>Space</kbd> | Toggles `selected` and emits `changed`; nothing on a selected chip with `[deselectable]="false"` |
|
|
214
|
+
|
|
215
|
+
## Inputs
|
|
216
|
+
|
|
217
|
+
| Name | Type | Default | Description |
|
|
218
|
+
| -------------- | ----------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
219
|
+
| `value` | `unknown` | `undefined` | The value this chip stands for inside a `bf-chip-group` (compared with `Object.is`); unused outside one. |
|
|
220
|
+
| `variant` | `BfChipVariant` (`'tonal' \| 'ink'`) | `'tonal'` | Selected treatment: tonal tint (default) or ink. |
|
|
221
|
+
| `disabled` | `boolean` | `false` | Disables the chip. |
|
|
222
|
+
| `label` | `string` | `''` | Label text; the default slot works too. |
|
|
223
|
+
| `size` | `BfSize \| undefined` (`'sm' \| 'md' \| 'lg' \| undefined`) | `undefined` | Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`controlSize`, `md` by default). |
|
|
224
|
+
| `deselectable` | `boolean` | `true` | When false, clicking an already selected chip does nothing (single-choice rows). |
|
|
225
|
+
| `selected` | `boolean` | `false` | Whether the chip is selected; two-way bindable. Inside a `single`-mode `bf-chip-group` the group's `value` decides and this is ignored. Two-way: `[(selected)]`. |
|
|
226
|
+
|
|
227
|
+
## Outputs
|
|
228
|
+
|
|
229
|
+
| Name | Payload | Description |
|
|
230
|
+
| --------- | --------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
231
|
+
| `changed` | `boolean` | Emitted with the new state after a user toggle. |
|
|
232
|
+
| `toggled` | `boolean` | Emitted with the new state after a user toggle, together with `changed`. **Deprecated** (0.3.0 use changed; removed in 0.4.0) |
|
|
233
|
+
|
|
234
|
+
## Slots
|
|
235
|
+
|
|
236
|
+
- `icon-start`: An icon before the label.
|
|
237
|
+
- `default`: Rich label content, before the `label` text.
|
|
238
|
+
|
|
239
|
+
## Methods
|
|
240
|
+
|
|
241
|
+
### `focus(options?: FocusOptions): void`
|
|
242
|
+
|
|
243
|
+
Focuses the chip's button.
|
|
244
|
+
|
|
245
|
+
| Parameter | Type | Description |
|
|
246
|
+
| ---------- | -------------- | --------------------------------------------------------------------- |
|
|
247
|
+
| `options?` | `FocusOptions` | Passed on to the native `focus()`, such as `{ preventScroll: true }`. |
|
|
248
|
+
|
|
249
|
+
## Notes
|
|
250
|
+
|
|
251
|
+
### Do
|
|
252
|
+
|
|
253
|
+
- Keep chip labels to one or two words.
|
|
254
|
+
- Use `bf-segmented` when the choices switch a whole view and there are two to four of them.
|
|
255
|
+
|
|
256
|
+
### Don't
|
|
257
|
+
|
|
258
|
+
- Don't use chips for status; that is `bf-badge`.
|
|
259
|
+
- Don't rely on truncation for long labels; a chip row should read at a glance.
|
|
260
|
+
|
|
261
|
+
## Migration notes
|
|
262
|
+
|
|
263
|
+
### 0.3.0
|
|
264
|
+
|
|
265
|
+
**Deprecated:** `toggled` → `changed`. The new `changed` output emits the new `selected` state
|
|
266
|
+
after a user toggle; `toggled` still emits the same value right after it until 0.4.0 (see
|
|
267
|
+
Migration 23).
|
|
268
|
+
|
|
269
|
+
**Breaking:** new `size` (`BfSize`; unset follows `provideBfDefaults()`'s `controlSize`): `sm` 32,
|
|
270
|
+
`md` 40 (default, was a fixed 36), `lg` 48 px. The hit extension applies only under a coarse
|
|
271
|
+
pointer and compensates the chip's 1.5 px border, so it reaches 44 px (was 42). See Migration 4.
|
|
272
|
+
|
|
273
|
+
**Behaviour:** shaped with the new `rounded-control` (`--radius-control`, `9999px` by default, so it renders as before); override the token to move off the pill.
|
|
274
|
+
|
|
275
|
+
JSDoc of `chip.component.ts` for the API reference: `@summary`/`@since` on the exported symbols;
|
|
276
|
+
`@slot` docs for `icon-start`, `default`; template handlers and framework hooks marked `@internal`,
|
|
277
|
+
so the reference leaves them out. No behaviour change.
|
|
278
|
+
|
|
279
|
+
**Behaviour:** a pressed state (F-045): unselected chips take `surface-pressed`, selected `tonal` ones `primary-soft-pressed`, selected `ink` ones `text-secondary` while held down. None while disabled; under forced colours the system colours win.
|
|
280
|
+
|
|
281
|
+
New `value = input<unknown>(undefined)`: what the chip stands for inside a `bf-chip-group`
|
|
282
|
+
(compared with `Object.is`); unused outside one. Inside a `single` group the chip renders
|
|
283
|
+
`role="radio"` with `aria-checked` (no `aria-pressed`), takes the group's roving `tabindex`, is
|
|
284
|
+
disabled with the group, and its own `selected` is ignored: the group's `value` decides. A
|
|
285
|
+
single-choice row without a group keeps working, and `deselectable` keeps its behaviour; the docs'
|
|
286
|
+
single-choice section now points to the group. New `focus(options?)` focuses the chip's button.
|
|
287
|
+
|
|
288
|
+
### 0.2.0
|
|
289
|
+
|
|
290
|
+
The unselected border is `border-strong` (hover `text-muted`). Disabled uses tokens instead of
|
|
291
|
+
`opacity-60`: `surface-sunken` / `text-disabled`, transparent border. The label renders in a
|
|
292
|
+
`data-label` span that truncates with an ellipsis; the chip and its host are capped at
|
|
293
|
+
`max-w-full`. Icon to label stays 6 px (the pill's proportion at 36 px; `bf-button` uses 8).
|
|
294
|
+
|
|
295
|
+
Fixed: pointer cursor while enabled; a selected chip now has a hover too (`tonal`
|
|
296
|
+
`primary-soft-hover`, `ink` `text-secondary`, fill and border).
|
|
297
|
+
|
|
298
|
+
### 0.1.0
|
|
299
|
+
|
|
300
|
+
New `bf-chip`: a toggleable pill for filters and tags, 36 px tall, with `tonal` (default) and `ink` treatments. Renders a `<button aria-pressed>` and shows a `::before` check mark while selected. Two-way `[(selected)]` model plus a `toggled` output fired after a user click; the hit area extends vertically with `::after`, matching `bf-button`. Fixed the check mark rendering as a thin vertical line instead of a tick: the `::before` pseudo-element had no `display` utility, and an inline, non-replaced box ignores explicit `width`/`height`; added `before:block`. Added `deselectable` (default `true`): set it `false` in a single-choice filter row so clicking the already-selected chip does nothing instead of clearing the selection. The unselected state's hover border is now `enabled:hover:border-border-strong` so a disabled chip doesn't show a hover state it can't act on.
|