mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 13:23:34 +00:00
[SM-645] Use search component in secrets manager (#4991)
* Move search component into the component library * Migrate search fields * Reshuffle imports slightly * Remove export input module --------- Co-authored-by: cd-bitwarden <106776772+cd-bitwarden@users.noreply.github.com>
This commit is contained in:
@@ -19,9 +19,10 @@ export * from "./navigation";
|
||||
export * from "./no-items";
|
||||
export * from "./progress";
|
||||
export * from "./radio-button";
|
||||
export * from "./search";
|
||||
export * from "./select";
|
||||
export * from "./table";
|
||||
export * from "./tabs";
|
||||
export * from "./toggle-group";
|
||||
export * from "./select";
|
||||
export * from "./typography";
|
||||
export * from "./utils/i18n-mock.service";
|
||||
|
||||
1
libs/components/src/search/index.ts
Normal file
1
libs/components/src/search/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./search.module";
|
||||
21
libs/components/src/search/search.component.html
Normal file
21
libs/components/src/search/search.component.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<label class="tw-sr-only" [for]="id">{{ "search" | i18n }}</label>
|
||||
<div class="tw-relative tw-flex tw-items-center">
|
||||
<label
|
||||
[for]="id"
|
||||
aria-hidden="true"
|
||||
class="tw-absolute tw-left-2 tw-z-20 !tw-mb-0 tw-cursor-text"
|
||||
>
|
||||
<i class="bwi bwi-search bwi-fw tw-text-muted"></i>
|
||||
</label>
|
||||
<input
|
||||
bitInput
|
||||
type="search"
|
||||
[id]="id"
|
||||
[placeholder]="placeholder ?? ('search' | i18n)"
|
||||
class="tw-rounded-l tw-pl-9"
|
||||
[ngModel]="searchText"
|
||||
(ngModelChange)="onChange($event)"
|
||||
(blur)="onTouch()"
|
||||
[disabled]="disabled"
|
||||
/>
|
||||
</div>
|
||||
54
libs/components/src/search/search.component.ts
Normal file
54
libs/components/src/search/search.component.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Component, Input } from "@angular/core";
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
|
||||
|
||||
let nextId = 0;
|
||||
|
||||
@Component({
|
||||
selector: "bit-search",
|
||||
templateUrl: "./search.component.html",
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
multi: true,
|
||||
useExisting: SearchComponent,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class SearchComponent implements ControlValueAccessor {
|
||||
private notifyOnChange: (v: string) => void;
|
||||
private notifyOnTouch: () => void;
|
||||
|
||||
protected id = `search-id-${nextId++}`;
|
||||
protected searchText: string;
|
||||
|
||||
@Input() disabled: boolean;
|
||||
@Input() placeholder: string;
|
||||
|
||||
onChange(searchText: string) {
|
||||
if (this.notifyOnChange != undefined) {
|
||||
this.notifyOnChange(searchText);
|
||||
}
|
||||
}
|
||||
|
||||
onTouch() {
|
||||
if (this.notifyOnTouch != undefined) {
|
||||
this.notifyOnTouch();
|
||||
}
|
||||
}
|
||||
|
||||
registerOnChange(fn: (v: string) => void): void {
|
||||
this.notifyOnChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void): void {
|
||||
this.notifyOnTouch = fn;
|
||||
}
|
||||
|
||||
writeValue(searchText: string): void {
|
||||
this.searchText = searchText;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean) {
|
||||
this.disabled = isDisabled;
|
||||
}
|
||||
}
|
||||
14
libs/components/src/search/search.module.ts
Normal file
14
libs/components/src/search/search.module.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
import { FormsModule } from "@angular/forms";
|
||||
|
||||
import { InputModule } from "../input/input.module";
|
||||
import { SharedModule } from "../shared";
|
||||
|
||||
import { SearchComponent } from "./search.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [SharedModule, InputModule, FormsModule],
|
||||
declarations: [SearchComponent],
|
||||
exports: [SearchComponent],
|
||||
})
|
||||
export class SearchModule {}
|
||||
40
libs/components/src/search/search.stories.ts
Normal file
40
libs/components/src/search/search.stories.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
import { Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
|
||||
import { InputModule } from "../input/input.module";
|
||||
import { I18nMockService } from "../utils/i18n-mock.service";
|
||||
|
||||
import { SearchComponent } from "./search.component";
|
||||
|
||||
export default {
|
||||
title: "Component Library/Form/Search",
|
||||
component: SearchComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [InputModule, FormsModule, ReactiveFormsModule, JslibModule],
|
||||
providers: [
|
||||
{
|
||||
provide: I18nService,
|
||||
useFactory: () => {
|
||||
return new I18nMockService({
|
||||
search: "Search",
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<SearchComponent> = (args: SearchComponent) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-search [(ngModel)]="searchText" [placeholder]="placeholder" [disabled]="disabled"></bit-search>
|
||||
`,
|
||||
});
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {};
|
||||
Reference in New Issue
Block a user