diff --git a/libs/components/src/checkbox/checkbox.stories.ts b/libs/components/src/checkbox/checkbox.stories.ts
index 0f6c7ef6ecd..c322f29b957 100644
--- a/libs/components/src/checkbox/checkbox.stories.ts
+++ b/libs/components/src/checkbox/checkbox.stories.ts
@@ -11,6 +11,7 @@ import { Meta, StoryObj, moduleMetadata } from "@storybook/angular";
import { I18nService } from "@bitwarden/common/src/platform/abstractions/i18n.service";
+import { BadgeModule } from "../badge";
import { FormControlModule } from "../form-control";
import { TableModule } from "../table";
import { I18nMockService } from "../utils/i18n-mock.service";
@@ -55,7 +56,14 @@ export default {
decorators: [
moduleMetadata({
declarations: [ExampleComponent],
- imports: [FormsModule, ReactiveFormsModule, FormControlModule, CheckboxModule, TableModule],
+ imports: [
+ FormsModule,
+ ReactiveFormsModule,
+ FormControlModule,
+ CheckboxModule,
+ TableModule,
+ BadgeModule,
+ ],
providers: [
{
provide: I18nService,
@@ -111,6 +119,14 @@ export const LongLabel: Story = {
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur iaculis consequat enim vitae elementum.
Ut non odio est.
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur iaculis consequat enim vitae elementum.
+ Ut non odio est.
+ Premium
+
+
`,
}),
diff --git a/libs/components/src/form-control/form-control.module.ts b/libs/components/src/form-control/form-control.module.ts
index 8a0377582c2..7582893ee3a 100644
--- a/libs/components/src/form-control/form-control.module.ts
+++ b/libs/components/src/form-control/form-control.module.ts
@@ -4,11 +4,11 @@ import { SharedModule } from "../shared";
import { FormControlComponent } from "./form-control.component";
import { BitHintComponent } from "./hint.component";
-import { BitLabel } from "./label.directive";
+import { BitLabel } from "./label.component";
@NgModule({
- imports: [SharedModule],
- declarations: [FormControlComponent, BitLabel, BitHintComponent],
+ imports: [SharedModule, BitLabel],
+ declarations: [FormControlComponent, BitHintComponent],
exports: [FormControlComponent, BitLabel, BitHintComponent],
})
export class FormControlModule {}
diff --git a/libs/components/src/form-control/label.component.html b/libs/components/src/form-control/label.component.html
new file mode 100644
index 00000000000..64ba1ce9501
--- /dev/null
+++ b/libs/components/src/form-control/label.component.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/components/src/form-control/label.directive.ts b/libs/components/src/form-control/label.component.ts
similarity index 53%
rename from libs/components/src/form-control/label.directive.ts
rename to libs/components/src/form-control/label.component.ts
index afec765c65d..1ab64d0ff94 100644
--- a/libs/components/src/form-control/label.directive.ts
+++ b/libs/components/src/form-control/label.component.ts
@@ -1,12 +1,16 @@
-import { Directive, ElementRef, HostBinding, Input, Optional } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { Component, ElementRef, HostBinding, Input, Optional } from "@angular/core";
import { FormControlComponent } from "./form-control.component";
// Increments for each instance of this component
let nextId = 0;
-@Directive({
+@Component({
selector: "bit-label",
+ standalone: true,
+ templateUrl: "label.component.html",
+ imports: [CommonModule],
})
export class BitLabel {
constructor(
@@ -15,16 +19,16 @@ export class BitLabel {
) {}
@HostBinding("class") @Input() get classList() {
- const classes = ["tw-inline-flex", "tw-gap-1", "tw-items-baseline", "tw-flex-row"];
- /**
- * We don't want to truncate checkboxes or radio buttons, which use form-control
- */
- return this.parentFormControl ? classes : classes.concat(["tw-truncate"]);
+ return ["tw-inline-flex", "tw-gap-1", "tw-items-baseline", "tw-flex-row", "tw-min-w-0"];
}
@HostBinding("title") get title() {
- return this.elementRef.nativeElement.textContent;
+ return this.elementRef.nativeElement.textContent.trim();
}
@HostBinding() @Input() id = `bit-label-${nextId++}`;
+
+ get isInsideFormControl() {
+ return !!this.parentFormControl;
+ }
}
diff --git a/libs/components/src/form-field/form-field.component.html b/libs/components/src/form-field/form-field.component.html
index d621e2fd695..2cf4db8d772 100644
--- a/libs/components/src/form-field/form-field.component.html
+++ b/libs/components/src/form-field/form-field.component.html
@@ -16,6 +16,30 @@
+
+
+
+
+
+
+
+
+
@@ -43,30 +67,6 @@
-
-
-
-
-
-
-
-
-
diff --git a/libs/components/src/form-field/form-field.component.ts b/libs/components/src/form-field/form-field.component.ts
index 4860185fee5..4944a793c43 100644
--- a/libs/components/src/form-field/form-field.component.ts
+++ b/libs/components/src/form-field/form-field.component.ts
@@ -12,7 +12,7 @@ import {
} from "@angular/core";
import { BitHintComponent } from "../form-control/hint.component";
-import { BitLabel } from "../form-control/label.directive";
+import { BitLabel } from "../form-control/label.component";
import { inputBorderClasses } from "../input/input.directive";
import { BitErrorComponent } from "./error.component";
diff --git a/libs/components/src/form-field/form-field.stories.ts b/libs/components/src/form-field/form-field.stories.ts
index 3557e3ad903..f5bb04bff0f 100644
--- a/libs/components/src/form-field/form-field.stories.ts
+++ b/libs/components/src/form-field/form-field.stories.ts
@@ -132,7 +132,7 @@ export const LabelWithIcon: Story = {
Label
-
+
@@ -160,6 +160,16 @@ export const LongLabel: Story = {
Optional Hint
+
+
+ Hello I am a very long label with lots of very cool helpful information
+
+
+
+
+
+ Optional Hint
+
`,
}),
@@ -252,7 +262,7 @@ export const Readonly: Story = {
- Textarea Premium
+ Textarea Premium
@@ -290,7 +300,12 @@ export const ButtonInputGroup: Story = {
props: args,
template: /*html*/ `
- Label
+
+ Label
+
+
+
+
diff --git a/libs/components/src/form/forms.mdx b/libs/components/src/form/forms.mdx
index dba6a1466c6..5ce129bf301 100644
--- a/libs/components/src/form/forms.mdx
+++ b/libs/components/src/form/forms.mdx
@@ -55,6 +55,18 @@ Be sure to use an appropriate type attribute on fields when defining new field c
`email` for email address or `number` for numerical information) to take advantage of newer input
controls like email verification, number selection, and more.
+Labels accept an optional `end` slot for any content that should not be truncated if the label text
+is too long, such as info link buttons or badges.
+
+```
+
+ Label text goes here
+
+
+
+
+```
+
#### Default with required attribute
@@ -86,6 +98,9 @@ button consists of a label and a radio input.
The full form control + label should be selectable to allow the user a larger click target.
+Labels accept an optional `end` slot for any content that is not part of the main label text, such
+as info link buttons or badges.
+
Radio groups should always have a default selected value.
Radio groups may optionally include extra helper text below each radio button.
@@ -112,6 +127,9 @@ Checkboxes can be displayed on their own or in a group (select multiple form que
displayed in a group, include an input Label and any associated required/validation logic for the
field.
+Labels accept an optional `end` slot for any content that is not part of the main label text, such
+as info link buttons or badges.
+
Unlike radio groups, checkbox groups are not required to have a default selected value.
Checkbox groups can include extra explanation text below each radio button or just the checkbox
diff --git a/libs/components/src/radio-button/radio-group.component.ts b/libs/components/src/radio-button/radio-group.component.ts
index 6a93ee07a6b..15d5fb32d1c 100644
--- a/libs/components/src/radio-button/radio-group.component.ts
+++ b/libs/components/src/radio-button/radio-group.component.ts
@@ -1,7 +1,7 @@
import { Component, ContentChild, HostBinding, Input, Optional, Self } from "@angular/core";
import { ControlValueAccessor, NgControl, Validators } from "@angular/forms";
-import { BitLabel } from "../form-control/label.directive";
+import { BitLabel } from "../form-control/label.component";
let nextId = 0;