mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 14:23:32 +00:00
[CL-50] Form controls (checkbox and radio) (#4066)
* [CL-50] feat: scaffold checkbox component * [CL-50] feat: implement control value accessor for checbox * [CL-50] feat: add form-field support to checkbox * [CL-50] feat: implement non-selected checkbox styling * [CL-50] feat: implement checkbox checked styles * [CL-50] feat: improve checkbox form-field compat * [CL-50] fix: checkbox border hover wrong color * [CL-50] feat: use svg instead of bwi font * [CL-50] feat: scaffold radio button * [EC-50] feat: implement radio logic * [CL-50] feat: add radio group tests * [CL-50] feat: add radio-button tests * [CL-50] feat: implement radio button styles * [CL-50] fix: checkbox style tweaks * [CL-50] feat: smooth radio button selection transition * [CL-50] chore: various fixes and cleanups * [CL-50] feat: add form field support * [EC-50] feat-wip: simplify checkbox styling * [EC-50] feat: extract checkbox into separate component * [CL-50] feat: add standalone form control component * [CL-50] feat: remove unnecessary checkbox-control It wasn't really doing anything, might as well use form control directly * [CL-50] chore: create separate folder with form examples * [CL-50] feat: switch to common bit-label * [CL-50] feat: let radio group act as form control * [CL-50] chore: restore form-field component * [CL-50] feat: add support for hint and error * [CL-50] fix: storybook build issue * [CL-50] fix: radio group label wrong text color * [CL-50] fix: translation * [CL-50] fix: put hint and errors outside label * [CL-50] feat: * [CL-50] feat: add custom checkbox example story * [CL-50] chore: remove 1 from full example name * [CL-50] chore: clean up unused icon * [CL-50] chore: clean up unused tailwind plugin * [CL-50] fix: ring offset color in custom example * [CL-50] chore: clean up unused icon * [CL-50] chore: add design link * [CL-50] chore: remove unused import * [CL-50] fix: pr review comments * [CL-50] fix: improve id handling
This commit is contained in:
104
libs/components/src/checkbox/checkbox.stories.ts
Normal file
104
libs/components/src/checkbox/checkbox.stories.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { FormsModule, ReactiveFormsModule, FormBuilder, Validators } from "@angular/forms";
|
||||
import { Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/src/abstractions/i18n.service";
|
||||
|
||||
import { FormControlModule } from "../form-control";
|
||||
import { I18nMockService } from "../utils/i18n-mock.service";
|
||||
|
||||
import { CheckboxModule } from "./checkbox.module";
|
||||
|
||||
const template = `
|
||||
<form [formGroup]="formObj">
|
||||
<bit-form-control>
|
||||
<input type="checkbox" bitCheckbox formControlName="checkbox">
|
||||
<bit-label>Click me</bit-label>
|
||||
</bit-form-control>
|
||||
</form>`;
|
||||
|
||||
@Component({
|
||||
selector: "app-example",
|
||||
template,
|
||||
})
|
||||
class ExampleComponent {
|
||||
protected formObj = this.formBuilder.group({
|
||||
checkbox: [false, Validators.requiredTrue],
|
||||
});
|
||||
|
||||
@Input() set checked(value: boolean) {
|
||||
this.formObj.patchValue({ checkbox: value });
|
||||
}
|
||||
|
||||
@Input() set disabled(disable: boolean) {
|
||||
if (disable) {
|
||||
this.formObj.disable();
|
||||
} else {
|
||||
this.formObj.enable();
|
||||
}
|
||||
}
|
||||
|
||||
constructor(private formBuilder: FormBuilder) {}
|
||||
}
|
||||
|
||||
export default {
|
||||
title: "Component Library/Form/Checkbox",
|
||||
component: ExampleComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
declarations: [ExampleComponent],
|
||||
imports: [FormsModule, ReactiveFormsModule, FormControlModule, CheckboxModule],
|
||||
providers: [
|
||||
{
|
||||
provide: I18nService,
|
||||
useFactory: () => {
|
||||
return new I18nMockService({
|
||||
required: "required",
|
||||
inputRequired: "Input is required.",
|
||||
inputEmail: "Input is not an email-address.",
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
parameters: {
|
||||
design: {
|
||||
type: "figma",
|
||||
url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library?node-id=3930%3A16850&t=xXPx6GJYsJfuMQPE-4",
|
||||
},
|
||||
},
|
||||
args: {
|
||||
checked: false,
|
||||
disabled: false,
|
||||
},
|
||||
} as Meta;
|
||||
|
||||
const DefaultTemplate: Story<ExampleComponent> = (args: ExampleComponent) => ({
|
||||
props: args,
|
||||
template: `<app-example [checked]="checked" [disabled]="disabled"></app-example>`,
|
||||
});
|
||||
|
||||
export const Default = DefaultTemplate.bind({});
|
||||
|
||||
const CustomTemplate: Story = (args) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<div class="tw-flex tw-flex-col tw-w-32">
|
||||
<label class="tw-text-main tw-flex tw-bg-secondary-300 tw-p-2 tw-items-baseline">
|
||||
A-Z
|
||||
<input class="tw-ml-auto focus-visible:tw-ring-offset-secondary-300" type="checkbox" bitCheckbox>
|
||||
</label>
|
||||
<label class="tw-text-main tw-flex tw-bg-secondary-300 tw-p-2 tw-items-baseline">
|
||||
a-z
|
||||
<input class="tw-ml-auto focus-visible:tw-ring-offset-secondary-300" type="checkbox" bitCheckbox>
|
||||
</label>
|
||||
<label class="tw-text-main tw-flex tw-bg-secondary-300 tw-p-2 tw-items-baseline">
|
||||
0-9
|
||||
<input class="tw-ml-auto focus-visible:tw-ring-offset-secondary-300" type="checkbox" bitCheckbox>
|
||||
</label>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
export const Custom = CustomTemplate.bind({});
|
||||
Reference in New Issue
Block a user