@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,455 @@
|
|
|
1
|
+
# bf-input
|
|
2
|
+
|
|
3
|
+
Single-line text field with label, help and error text, icon slots and Signal Forms binding
|
|
4
|
+
|
|
5
|
+
`BfInputComponent` from `@bitforgehq/ui` · Forms · since 0.1.0
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Component, signal } from '@angular/core';
|
|
11
|
+
import { BfInputComponent } from '@bitforgehq/ui';
|
|
12
|
+
import { BfIconComponent } from '@bitforgehq/ui/icons';
|
|
13
|
+
import { Search } from 'lucide';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The bf-input overview.
|
|
17
|
+
*
|
|
18
|
+
* Live demo of `bf-input`: a bound default field with an echo, an icon-start search field, an error state and a readonly field; then the sm, md and lg sizes in a row.
|
|
19
|
+
*/
|
|
20
|
+
@Component({
|
|
21
|
+
selector: 'app-example-input-overview',
|
|
22
|
+
imports: [BfInputComponent, BfIconComponent],
|
|
23
|
+
template: `
|
|
24
|
+
<div class="flex flex-col gap-3">
|
|
25
|
+
<bf-input label="Project name" placeholder="Atlas rebrand" [(value)]="projectName" />
|
|
26
|
+
<p data-status aria-live="polite" class="text-caption text-text-muted">
|
|
27
|
+
{{ projectName() ? 'Project: ' + projectName() : 'Type a project name.' }}
|
|
28
|
+
</p>
|
|
29
|
+
<bf-input label="Search" type="search" [iconStart]="true">
|
|
30
|
+
<bf-icon bfSlot="icon-start" [icon]="search" />
|
|
31
|
+
</bf-input>
|
|
32
|
+
<bf-input label="Email" errorMessage="Enter a valid email address" value="lena@studio" />
|
|
33
|
+
<bf-input label="Owner" value="Lena Moser" [readonly]="true" />
|
|
34
|
+
<div data-sizes class="flex flex-wrap items-center gap-3">
|
|
35
|
+
<bf-input size="sm" ariaLabel="Small field" placeholder="sm · 32 px" class="w-40" />
|
|
36
|
+
<bf-input ariaLabel="Medium field" placeholder="md · 40 px" class="w-40" />
|
|
37
|
+
<bf-input size="lg" ariaLabel="Large field" placeholder="lg · 48 px" class="w-40" />
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
`,
|
|
41
|
+
})
|
|
42
|
+
export class InputOverviewExampleComponent {
|
|
43
|
+
readonly search = Search;
|
|
44
|
+
readonly projectName = signal('');
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Overview
|
|
49
|
+
|
|
50
|
+
Single-line text field with label, help and error text, icon slots and Signal Forms binding.
|
|
51
|
+
Bind `[(value)]` directly or `[formField]` from a signal form; the field state (touched,
|
|
52
|
+
invalid, errors, disabled, readonly, required) flows in through the matching inputs.
|
|
53
|
+
|
|
54
|
+
The text field for one line of input: email, password, search, numbers. It renders its own label, helper and error text through `bf-field`, so a form is a list of `bf-input`s with no extra markup.
|
|
55
|
+
|
|
56
|
+
## When to use
|
|
57
|
+
|
|
58
|
+
Use `bf-input` for one line of text: a name, an email, a password, a search term, a date. Use [bf-textarea](https://bitforge-ui.web.app/components/textarea) instead for text that runs over several lines, [bf-number-input](https://bitforge-ui.web.app/components/number-input) for a value bound as a `number`, and [bf-select](https://bitforge-ui.web.app/components/select) when the answer is one of a known list.
|
|
59
|
+
|
|
60
|
+
## Basic usage
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { Component, signal } from '@angular/core';
|
|
64
|
+
import { BfInputComponent } from '@bitforgehq/ui';
|
|
65
|
+
|
|
66
|
+
/** A labelled text field bound to a signal. */
|
|
67
|
+
@Component({
|
|
68
|
+
selector: 'app-example-input-basic',
|
|
69
|
+
imports: [BfInputComponent],
|
|
70
|
+
template: `
|
|
71
|
+
<div class="flex flex-col gap-2">
|
|
72
|
+
<bf-input label="Project name" placeholder="Atlas rebrand" [(value)]="name" />
|
|
73
|
+
<p class="text-caption text-text-muted">Name: {{ name() || '(empty)' }}</p>
|
|
74
|
+
</div>
|
|
75
|
+
`,
|
|
76
|
+
})
|
|
77
|
+
export class InputBasicExampleComponent {
|
|
78
|
+
protected readonly name = signal('');
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`(changed)` emits the new text right after each user edit (a keystroke or a paste), the moment
|
|
83
|
+
`value` changes; a programmatic write to `value` does not emit.
|
|
84
|
+
|
|
85
|
+
## With Signal Forms
|
|
86
|
+
|
|
87
|
+
Bind the field instead of the value. Touched, invalid, errors, disabled, readonly and required flow in automatically; the first error shows once the user leaves the field. A validator's `message` becomes the text; one without a message shows its kind's default text (see Validation). `[formRoot]` turns off the browser's validation bubbles and runs the form's `submission` on submit. The [Forms and validation guide](https://bitforge-ui.web.app/forms) has a complete, compiled example.
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { Component, signal } from '@angular/core';
|
|
91
|
+
import { FormField, FormRoot, email, form, required } from '@angular/forms/signals';
|
|
92
|
+
import { BfButtonComponent, BfInputComponent } from '@bitforgehq/ui';
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* An email field on Signal Forms.
|
|
96
|
+
*
|
|
97
|
+
* `[formField]` carries touched, invalid, errors, disabled, readonly and required; the
|
|
98
|
+
* validators' messages become the error text. `[formRoot]` runs the submission on submit.
|
|
99
|
+
*/
|
|
100
|
+
@Component({
|
|
101
|
+
selector: 'app-example-input-signal-forms',
|
|
102
|
+
imports: [FormField, FormRoot, BfButtonComponent, BfInputComponent],
|
|
103
|
+
template: `
|
|
104
|
+
<form [formRoot]="signup" class="flex flex-col items-start gap-3">
|
|
105
|
+
<bf-input label="Email" type="email" class="self-stretch" [formField]="signup.email" />
|
|
106
|
+
<bf-button type="submit">Sign up</bf-button>
|
|
107
|
+
</form>
|
|
108
|
+
`,
|
|
109
|
+
})
|
|
110
|
+
export class InputSignalFormsExampleComponent {
|
|
111
|
+
private readonly model = signal({ email: '' });
|
|
112
|
+
protected readonly signup = form(
|
|
113
|
+
this.model,
|
|
114
|
+
(p) => {
|
|
115
|
+
required(p.email, { message: 'Enter your email' });
|
|
116
|
+
email(p.email, { message: 'Enter a valid email address' });
|
|
117
|
+
},
|
|
118
|
+
{ submission: { action: () => Promise.resolve(undefined) } },
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Icons
|
|
124
|
+
|
|
125
|
+
Set `iconStart` / `iconEnd` to reserve the space, then project the icon into the slot.
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { Component, signal } from '@angular/core';
|
|
129
|
+
import { BfInputComponent } from '@bitforgehq/ui';
|
|
130
|
+
import { BfIconComponent } from '@bitforgehq/ui/icons';
|
|
131
|
+
import { Search } from 'lucide';
|
|
132
|
+
|
|
133
|
+
/** A search field with an icon in its icon-start slot. */
|
|
134
|
+
@Component({
|
|
135
|
+
selector: 'app-example-input-icons',
|
|
136
|
+
imports: [BfInputComponent, BfIconComponent],
|
|
137
|
+
template: `
|
|
138
|
+
<bf-input label="Search" type="search" [iconStart]="true" [(value)]="query">
|
|
139
|
+
<bf-icon bfSlot="icon-start" [icon]="search" />
|
|
140
|
+
</bf-input>
|
|
141
|
+
`,
|
|
142
|
+
})
|
|
143
|
+
export class InputIconsExampleComponent {
|
|
144
|
+
protected readonly search = Search;
|
|
145
|
+
protected readonly query = signal('');
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Search fields and other unlabelled inputs
|
|
150
|
+
|
|
151
|
+
Skip the visible `label` when the field itself makes its purpose clear (a toolbar search box) and
|
|
152
|
+
give it `ariaLabel` instead so assistive tech still gets a name; help and error wiring keep working
|
|
153
|
+
the same way. When a visible heading already names the field, point `ariaLabelledby` at its id.
|
|
154
|
+
A field without a visible label needs one of the two.
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { Component, signal } from '@angular/core';
|
|
158
|
+
import { BfInputComponent } from '@bitforgehq/ui';
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Fields without a visible label.
|
|
162
|
+
*
|
|
163
|
+
* A toolbar search named by `ariaLabel`, and a budget field named by the heading it points at.
|
|
164
|
+
*/
|
|
165
|
+
@Component({
|
|
166
|
+
selector: 'app-example-input-unlabelled',
|
|
167
|
+
imports: [BfInputComponent],
|
|
168
|
+
template: `
|
|
169
|
+
<div class="flex flex-col gap-3">
|
|
170
|
+
<bf-input type="search" ariaLabel="Search projects" [(value)]="query" />
|
|
171
|
+
<h3 id="input-budget-heading" class="text-heading">Budget</h3>
|
|
172
|
+
<bf-input ariaLabelledby="input-budget-heading" [(value)]="budget" />
|
|
173
|
+
</div>
|
|
174
|
+
`,
|
|
175
|
+
})
|
|
176
|
+
export class InputUnlabelledExampleComponent {
|
|
177
|
+
protected readonly query = signal('');
|
|
178
|
+
protected readonly budget = signal('');
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Native constraints and keyboards
|
|
183
|
+
|
|
184
|
+
`maxLength`, `minLength`, `min`, `max`, `step` and `pattern` reach the native `<input>`, so the
|
|
185
|
+
browser enforces length limits and date pickers respect the range. Signal Forms binds them from
|
|
186
|
+
its rules (`maxLength(p.code, 20)` renders `maxlength="20"`; exactly one `pattern()` renders the
|
|
187
|
+
native `pattern` when its flags are empty, `u` or `v`; a pattern with other flags such as `i`, or
|
|
188
|
+
several patterns, is left to the form, because HTML compiles the attribute without them).
|
|
189
|
+
`inputMode`, `enterKeyHint`, `spellcheck` and `autocapitalize` pick the right
|
|
190
|
+
phone keyboard (`BfInputInputMode`, `BfInputEnterKeyHint` and `BfInputAutocapitalize`: a
|
|
191
|
+
`BfInputMode`, `BfEnterKeyHint` or `BfAutocapitalize` keyword, or `''`, the default, which leaves
|
|
192
|
+
the attribute off). The `date`, `time`, `datetime-local` and `month` types open the platform's own
|
|
193
|
+
picker.
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
import { Component, signal } from '@angular/core';
|
|
197
|
+
import { BfInputComponent } from '@bitforgehq/ui';
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Native constraints and keyboard hints.
|
|
201
|
+
*
|
|
202
|
+
* A date range, a six-digit code with the numeric keyboard, and a city field that capitalises
|
|
203
|
+
* words and skips spell checking.
|
|
204
|
+
*/
|
|
205
|
+
@Component({
|
|
206
|
+
selector: 'app-example-input-native',
|
|
207
|
+
imports: [BfInputComponent],
|
|
208
|
+
template: `
|
|
209
|
+
<div class="flex flex-col gap-3">
|
|
210
|
+
<bf-input label="Start" type="date" min="2026-01-01" max="2026-12-31" [(value)]="start" />
|
|
211
|
+
<bf-input
|
|
212
|
+
label="Code"
|
|
213
|
+
[maxLength]="6"
|
|
214
|
+
inputMode="numeric"
|
|
215
|
+
enterKeyHint="next"
|
|
216
|
+
[(value)]="code"
|
|
217
|
+
/>
|
|
218
|
+
<bf-input label="City" autocapitalize="words" [spellcheck]="false" [(value)]="city" />
|
|
219
|
+
</div>
|
|
220
|
+
`,
|
|
221
|
+
})
|
|
222
|
+
export class InputNativeExampleComponent {
|
|
223
|
+
protected readonly start = signal('');
|
|
224
|
+
protected readonly code = signal('');
|
|
225
|
+
protected readonly city = signal('');
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Sizes and states
|
|
230
|
+
|
|
231
|
+
One `BfSize` scale for every field and control: `sm` 32 px, `md` 40 px (default), `lg` 48 px, so an input lines up with the buttons, selects, chips and segmented controls of the same step. Unset, `size` follows `provideBfDefaults()`'s `fieldSize`, `md` by default; a Capacitor app sets `provideBfDefaults({ fieldSize: 'lg' })` once for the 48 px phone look, and a dense sub-tree (a filter bar, a table) can set `{ size: 'sm' }` in a component's `providers`. Fields get no touch extension: `sm`/`md` fields stay 32/40 px under a coarse pointer, so touch apps use `provideBfDefaults({ fieldSize: 'lg' })`. Icon insets and padding use logical properties, so `icon-start` sits at the inline start under `dir="rtl"` too. `disabled`, `readonly` and `errorMessage` render the design's states.
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
import { Component, signal } from '@angular/core';
|
|
235
|
+
import { BfInputComponent } from '@bitforgehq/ui';
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Field sizes and states.
|
|
239
|
+
*
|
|
240
|
+
* The sm, md and lg steps, a read-only field and one with an explicit error message.
|
|
241
|
+
*/
|
|
242
|
+
@Component({
|
|
243
|
+
selector: 'app-example-input-sizes',
|
|
244
|
+
imports: [BfInputComponent],
|
|
245
|
+
template: `
|
|
246
|
+
<div class="flex flex-col gap-3">
|
|
247
|
+
<bf-input size="sm" ariaLabel="Filter" [(value)]="filter" />
|
|
248
|
+
<bf-input label="Project name" [(value)]="name" />
|
|
249
|
+
<bf-input size="lg" label="Title" [(value)]="title" />
|
|
250
|
+
<bf-input label="Owner" value="Lena Moser" [readonly]="true" />
|
|
251
|
+
<bf-input label="Email" errorMessage="Enter a valid email address" />
|
|
252
|
+
</div>
|
|
253
|
+
`,
|
|
254
|
+
})
|
|
255
|
+
export class InputSizesExampleComponent {
|
|
256
|
+
protected readonly filter = signal('');
|
|
257
|
+
protected readonly name = signal('Atlas rebrand');
|
|
258
|
+
protected readonly title = signal('');
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Validation
|
|
263
|
+
|
|
264
|
+
Once the control is touched it shows the first error as text: the error's own `message`, else the default for its kind from `provideBfLabels()`'s `validation` labels (`required` "Fill in this field", `email`, `pattern`, `parse`, `min(n)`, `max(n)`, `minLength(n)` "Use at least n characters", `maxLength(n)`, `minDate(d)`, `maxDate(d)`, and `fallback` "Check this value" for any other kind), so it never turns red without text. Reactive Forms `Validators.*` errors carry no message and get the same defaults (`minlength`/`maxlength` read their limit from the error's `context`). An explicit `errorMessage` wins over both and shows at once, e.g. for a server error.
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
import { Component, signal } from '@angular/core';
|
|
268
|
+
import { FormField, FormRoot, email, form, required } from '@angular/forms/signals';
|
|
269
|
+
import { BfButtonComponent, BfInputComponent } from '@bitforgehq/ui';
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Default and explicit error text.
|
|
273
|
+
*
|
|
274
|
+
* The first field's validators carry no message, so a submit shows the defaults; the second
|
|
275
|
+
* field's `errorMessage` (a server error) shows at once.
|
|
276
|
+
*/
|
|
277
|
+
@Component({
|
|
278
|
+
selector: 'app-example-input-validation',
|
|
279
|
+
imports: [FormField, FormRoot, BfButtonComponent, BfInputComponent],
|
|
280
|
+
template: `
|
|
281
|
+
<form [formRoot]="signup" class="flex flex-col items-start gap-3">
|
|
282
|
+
<bf-input label="Email" type="email" class="self-stretch" [formField]="signup.email" />
|
|
283
|
+
<bf-input
|
|
284
|
+
label="Backup email"
|
|
285
|
+
class="self-stretch"
|
|
286
|
+
errorMessage="This address is already registered"
|
|
287
|
+
/>
|
|
288
|
+
<bf-button type="submit">Sign up</bf-button>
|
|
289
|
+
</form>
|
|
290
|
+
`,
|
|
291
|
+
})
|
|
292
|
+
export class InputValidationExampleComponent {
|
|
293
|
+
private readonly model = signal({ email: '' });
|
|
294
|
+
protected readonly signup = form(
|
|
295
|
+
this.model,
|
|
296
|
+
(p) => {
|
|
297
|
+
required(p.email);
|
|
298
|
+
email(p.email);
|
|
299
|
+
},
|
|
300
|
+
{ submission: { action: () => Promise.resolve(undefined) } },
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Desktop
|
|
306
|
+
|
|
307
|
+
The field has no hover state; the text cursor shows over it. The `primary` border and the focus ring show on every focus, by mouse or keyboard, because a focused field takes typing. Fields default to `md` (40 px); `provideBfDefaults({ fieldSize: 'sm' })`, or `{ size: 'sm' }` in a component's `providers`, gives 32 px fields for a dense filter bar or table ([density guide](https://bitforge-ui.web.app/density)).
|
|
308
|
+
|
|
309
|
+
## Theming
|
|
310
|
+
|
|
311
|
+
- Border: `border-strong` (the control boundary, ≥ 3:1), switching to `danger-border` on error; focus: `primary` border with a `ring` ring.
|
|
312
|
+
- Disabled: `surface-sunken` border, `surface-muted` background, `text-disabled` text. Read-only: `surface-muted` background. Placeholder: `text-muted` (≥ 4.5:1). Icon slots: `text-subtle`.
|
|
313
|
+
- Label, help and error text come from the `bf-field` wrapper (see its Theming section).
|
|
314
|
+
|
|
315
|
+
## Accessibility
|
|
316
|
+
|
|
317
|
+
Native `<input>`, with `type` reflecting the `type` input so mobile keyboards match. `bf-field` renders the `<label for>`; the input itself wires `aria-describedby` to the help paragraph and the error paragraph under it (both while shown, help first) and, while it is invalid, `aria-errormessage` to the error paragraph; `aria-invalid` is set once the field is touched and invalid (an explicit `errorMessage` shows immediately). `required` reflects the native attribute as well as the label's required marker. `aria-label` and `aria-labelledby` carry `ariaLabel` and `ariaLabelledby` only while there is no visible `label`, so a `label` and an `ariaLabel` given together never fight over the accessible name — the visible label always wins and the other two are ignored. A field without a visible label needs `ariaLabel` or `ariaLabelledby`. `readonly` uses the native attribute: the value can be selected and copied, the input stays in the tab order, and assistive tech announces it as read-only. `focus()` focuses the native input; Signal Forms calls it from `focusBoundControl()`, so "focus the first invalid field" works.
|
|
318
|
+
|
|
319
|
+
### Keyboard
|
|
320
|
+
|
|
321
|
+
The input is a native `<input>`: typing, selection and the date and time pickers are the browser's own.
|
|
322
|
+
|
|
323
|
+
| Key | Action |
|
|
324
|
+
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------- |
|
|
325
|
+
| <kbd>Tab</kbd> / <kbd>Shift</kbd>+<kbd>Tab</kbd> | Moves focus to and from the field; a `readonly` field stays in the tab order, a `disabled` one is skipped |
|
|
326
|
+
| <kbd>Enter</kbd> | Inside a `<form>` with a submit button, submits the form (the browser's implicit submission) |
|
|
327
|
+
|
|
328
|
+
## Inputs
|
|
329
|
+
|
|
330
|
+
| Name | Type | Default | Description |
|
|
331
|
+
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
332
|
+
| `type` | `BfInputType` (`'text' \| 'email' \| 'password' \| 'number' \| 'tel' \| 'url' \| 'search' \| 'date' \| 'time' \| 'datetime-local' \| 'month'`) | `'text'` | Native input type; the value stays a string. For numbers use `bf-number-input`, which binds `number \| null`. |
|
|
333
|
+
| `size` | `BfSize \| undefined` (`'sm' \| 'md' \| 'lg' \| undefined`) | `undefined` | Height step: sm 32, md 40, lg 48 px; unset follows `provideBfDefaults()` (`fieldSize`, `md` by default). |
|
|
334
|
+
| `label` | `string` | `''` | Visible label above the control. |
|
|
335
|
+
| `ariaLabel` | `string` | `''` | Accessible name when no visible label is rendered (e.g. a search field). Ignored when `label` is set. |
|
|
336
|
+
| `ariaLabelledby` | `string` | `''` | Id(s) of the element(s) that name the field when no visible label is rendered. Ignored when `label` is set. |
|
|
337
|
+
| `placeholder` | `string` | `''` | Example value shown while empty. |
|
|
338
|
+
| `helpText` | `string` | `''` | Helper text under the control. |
|
|
339
|
+
| `errorMessage` | `string` | `''` | Explicit error text; takes precedence over Signal Forms errors. |
|
|
340
|
+
| `disabled` | `boolean` | `false` | Disables the control. Set by `[formField]`; do not bind it yourself. |
|
|
341
|
+
| `readonly` | `boolean` | `false` | Makes the control read-only. Set by `[formField]`; do not bind it yourself. |
|
|
342
|
+
| `required` | `boolean` | `false` | Marks the control required (label marker and native attribute). Set by `[formField]`; do not bind it yourself. |
|
|
343
|
+
| `invalid` | `boolean` | `false` | Field validity from Signal Forms. Set by `[formField]`; do not bind it yourself. |
|
|
344
|
+
| `touched` | `boolean` | `false` | Whether the user has left the field; errors show only once touched. Set by `[formField]`; do not bind it yourself. |
|
|
345
|
+
| `errors` | `readonly ValidationError.WithOptionalFieldTree[]` | `[]` | Validation errors from Signal Forms; the first message is shown once touched. Set by `[formField]`; do not bind it yourself. |
|
|
346
|
+
| `name` | `string` | `''` | Native name attribute. Set by `[formField]`; do not bind it yourself. |
|
|
347
|
+
| `id` | `string` | `generated` | Control id; generated when not set. |
|
|
348
|
+
| `iconStart` | `boolean` | `false` | Reserve space for an icon in the `icon-start` slot. |
|
|
349
|
+
| `iconEnd` | `boolean` | `false` | Reserve space for an icon in the `icon-end` slot. |
|
|
350
|
+
| `autocomplete` | `string` | `''` | Native autocomplete hint. |
|
|
351
|
+
| `maxLength` | `number \| undefined` | `undefined` | Maximum number of characters (native `maxlength`); bound by Signal Forms `maxLength()`. Set by `[formField]`; do not bind it yourself. |
|
|
352
|
+
| `minLength` | `number \| undefined` | `undefined` | Minimum number of characters (native `minlength`); bound by Signal Forms `minLength()`. Set by `[formField]`; do not bind it yourself. |
|
|
353
|
+
| `min` | `string \| undefined` | `undefined` | Lowest value (native `min`), e.g. `2026-01-01` for a date or `0` for a number. Set by `[formField]`; do not bind it yourself. |
|
|
354
|
+
| `max` | `string \| undefined` | `undefined` | Highest value (native `max`), e.g. `2026-12-31` for a date or `100` for a number. Set by `[formField]`; do not bind it yourself. |
|
|
355
|
+
| `step` | `string \| number \| undefined` | `undefined` | Step between valid values (native `step`), e.g. `0.5` or `any`. |
|
|
356
|
+
| `pattern` | `readonly RegExp[]` | `[]` | Patterns from Signal Forms `pattern()`; exactly one, with no flags or only `u`/`v`, is rendered as the native `pattern`. Set by `[formField]`; do not bind it yourself. |
|
|
357
|
+
| `inputMode` | `BfInputInputMode` (`'none' \| 'text' \| 'decimal' \| 'numeric' \| 'tel' \| 'search' \| 'email' \| 'url' \| ''`) | `''` | Virtual keyboard to show (native `inputmode`). |
|
|
358
|
+
| `enterKeyHint` | `BfInputEnterKeyHint` (`'enter' \| 'done' \| 'go' \| 'next' \| 'previous' \| 'search' \| 'send' \| ''`) | `''` | Label of the virtual keyboard's Enter key (native `enterkeyhint`). |
|
|
359
|
+
| `spellcheck` | `boolean \| undefined` | `undefined` | Spell checking on or off (native `spellcheck`); the browser decides while unset. |
|
|
360
|
+
| `autocapitalize` | `BfInputAutocapitalize` (`'off' \| 'none' \| 'on' \| 'sentences' \| 'words' \| 'characters' \| ''`) | `''` | Capitalisation of typed text on virtual keyboards (native `autocapitalize`). |
|
|
361
|
+
| `value` | `string` | `''` | The text value; two-way bindable and bound by `[formField]`. Two-way: `[(value)]`. |
|
|
362
|
+
|
|
363
|
+
## Outputs
|
|
364
|
+
|
|
365
|
+
| Name | Payload | Description |
|
|
366
|
+
| --------- | ------------ | ------------------------------------------------------------------------------------------------------- |
|
|
367
|
+
| `changed` | `string` | Emitted with the new text right after the user changes it (each keystroke or paste). |
|
|
368
|
+
| `focused` | `FocusEvent` | Emitted when the control gains focus. |
|
|
369
|
+
| `blurred` | `FocusEvent` | Emitted when the control loses focus. |
|
|
370
|
+
| `touch` | `void` | Emitted on blur so Signal Forms marks the field touched. Set by `[formField]`; do not bind it yourself. |
|
|
371
|
+
|
|
372
|
+
## Slots
|
|
373
|
+
|
|
374
|
+
- `icon-start`: An icon inside the field, before the text.
|
|
375
|
+
- `icon-end`: An icon inside the field, after the text.
|
|
376
|
+
|
|
377
|
+
## Methods
|
|
378
|
+
|
|
379
|
+
### `focus(options?: FocusOptions): void`
|
|
380
|
+
|
|
381
|
+
Focuses the native input; Signal Forms calls it from `focusBoundControl()`.
|
|
382
|
+
|
|
383
|
+
| Parameter | Type | Description |
|
|
384
|
+
| ---------- | -------------- | --------------------------------------------------------------------- |
|
|
385
|
+
| `options?` | `FocusOptions` | Passed on to the native `focus()`, such as `{ preventScroll: true }`. |
|
|
386
|
+
|
|
387
|
+
## Notes
|
|
388
|
+
|
|
389
|
+
### Do
|
|
390
|
+
|
|
391
|
+
- Always set `label`, or `ariaLabel` / `ariaLabelledby` when the field shows no visible label (e.g. a search box).
|
|
392
|
+
- Use the right `type` so mobile keyboards match (email, tel, url); for a number bound as a `number`, use `bf-number-input`.
|
|
393
|
+
- Let Signal Forms drive validation; use `errorMessage` only for server-side errors.
|
|
394
|
+
|
|
395
|
+
### Don't
|
|
396
|
+
|
|
397
|
+
- Don't use `placeholder` as the label.
|
|
398
|
+
- Don't bind both `[(value)]` and `[formField]`.
|
|
399
|
+
|
|
400
|
+
## Migration notes
|
|
401
|
+
|
|
402
|
+
### 0.3.0
|
|
403
|
+
|
|
404
|
+
New `changed` output: the new text right after each user edit (not for a programmatic write), so
|
|
405
|
+
every value control has one `changed`. New exported `BfInputInputMode` (`BfInputMode | ''`),
|
|
406
|
+
`BfInputEnterKeyHint` (`BfEnterKeyHint | ''`) and `BfInputAutocapitalize`
|
|
407
|
+
(`BfAutocapitalize | ''`), the types of `inputMode`, `enterKeyHint` and `autocapitalize` (were
|
|
408
|
+
the same unions written inline; `''`, the default, leaves the attribute off). `BfInputMode`,
|
|
409
|
+
`BfEnterKeyHint` and `BfAutocapitalize` keep their 0.2.0 members (their `@since` now says 0.2.0).
|
|
410
|
+
|
|
411
|
+
**Breaking:** the default `size` is `md` (40 px) instead of `lg` (48 px); `size` is a `BfSize`
|
|
412
|
+
(`sm` 32, `md` 40, `lg` 48 px — `sm` is new) and, unset, follows `provideBfDefaults()`'s
|
|
413
|
+
`fieldSize`. See Migration 2. Icon insets and padding are logical (`start-*`/`end-*`, `ps-*`/`pe-*`),
|
|
414
|
+
so `icon-start` and `icon-end` sit at the inline start and end under `dir="rtl"`.
|
|
415
|
+
|
|
416
|
+
**Behaviour:** an error without a message shows its kind's default text (was a red border only):
|
|
417
|
+
once touched, the field shows the first error's own `message`, else `provideBfLabels()`'s
|
|
418
|
+
`validation` text for its kind (Signal Forms and Reactive interop kinds), else
|
|
419
|
+
`validation.fallback`. `errorMessage` still wins. See Migration 1.
|
|
420
|
+
|
|
421
|
+
JSDoc of `input.component.ts` for the API reference: `@summary`/`@since` on the exported symbols;
|
|
422
|
+
`@slot` docs for `icon-start`, `icon-end`; `@param` docs; template handlers and framework hooks
|
|
423
|
+
marked `@internal`, so the reference leaves them out. No behaviour change.
|
|
424
|
+
|
|
425
|
+
**Behaviour:** the help text stays while an error shows, with the error under it (F-020):
|
|
426
|
+
`aria-describedby` lists both (`"<id>-help <id>-error"`), and `aria-errormessage` points at the
|
|
427
|
+
error paragraph while `aria-invalid="true"`. See Migration 25.
|
|
428
|
+
|
|
429
|
+
### 0.2.0
|
|
430
|
+
|
|
431
|
+
The rest border is `border-strong` (was `border`, 1.32:1) and the placeholder `text-muted` (was
|
|
432
|
+
`text-subtle`, 2.73:1); the icon slots stay `text-subtle`.
|
|
433
|
+
|
|
434
|
+
Changed: the border narrows to 1 px (was 1.5 px); contrast stays ≥ 3:1.
|
|
435
|
+
|
|
436
|
+
Changed: the focus ring narrows to 2 px (was 4 px); it still shows on mouse focus, not just
|
|
437
|
+
keyboard focus.
|
|
438
|
+
|
|
439
|
+
Added: `ariaLabel` input (mirrors `bf-toggle`) sets `aria-label` on the native input for a field
|
|
440
|
+
with no visible `label` (e.g. a search box); ignored while `label` is set, so the visible label
|
|
441
|
+
stays the sole accessible name.
|
|
442
|
+
|
|
443
|
+
Added: `maxLength`, `minLength`, `min`, `max`, `step`, `pattern` (exactly one pattern with no flags,
|
|
444
|
+
`u` or `v` renders the native attribute; other flags such as `i` cannot be expressed in HTML, so the
|
|
445
|
+
form alone validates them), `inputMode`, `enterKeyHint`, `spellcheck` and `autocapitalize` inputs,
|
|
446
|
+
each rendered on the native `<input>` only when set; Signal Forms binds the constraint rules to them
|
|
447
|
+
(`maxLength(p.code, 20)` renders `maxlength="20"`). New exported types `BfInputMode`,
|
|
448
|
+
`BfEnterKeyHint` and `BfAutocapitalize`. `BfInputType` adds `date`, `time`, `datetime-local` and
|
|
449
|
+
`month`, which open the native picker. `ariaLabelledby` sets `aria-labelledby` while there is no
|
|
450
|
+
visible `label`. `focus(options?)` focuses the native control, so Signal Forms'
|
|
451
|
+
`focusBoundControl()` and "focus the first invalid field" on submit now work (they were no-ops).
|
|
452
|
+
|
|
453
|
+
### 0.1.0
|
|
454
|
+
|
|
455
|
+
Field sizes renamed: `sm`/`md` (40/48 px) is now `md`/`lg` (40/48 px), default stays 48 px but the default token changed to `lg`. The host no longer reflects a static `id` attribute onto `<bf-input>`; the id lands only on the native `<input>`.
|