-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CL-500] Add disclosure component and directive (#11865)
- Loading branch information
Showing
9 changed files
with
152 additions
and
15 deletions.
There are no files selected for viewing
27 changes: 27 additions & 0 deletions
27
libs/components/src/disclosure/disclosure-trigger-for.directive.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { Directive, HostBinding, HostListener, Input } from "@angular/core"; | ||
|
||
import { DisclosureComponent } from "./disclosure.component"; | ||
|
||
@Directive({ | ||
selector: "[bitDisclosureTriggerFor]", | ||
exportAs: "disclosureTriggerFor", | ||
standalone: true, | ||
}) | ||
export class DisclosureTriggerForDirective { | ||
/** | ||
* Accepts template reference for a bit-disclosure component instance | ||
*/ | ||
@Input("bitDisclosureTriggerFor") disclosure: DisclosureComponent; | ||
|
||
@HostBinding("attr.aria-expanded") get ariaExpanded() { | ||
return this.disclosure.open; | ||
} | ||
|
||
@HostBinding("attr.aria-controls") get ariaControls() { | ||
return this.disclosure.id; | ||
} | ||
|
||
@HostListener("click") click() { | ||
this.disclosure.open = !this.disclosure.open; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { Component, HostBinding, Input, booleanAttribute } from "@angular/core"; | ||
|
||
let nextId = 0; | ||
|
||
@Component({ | ||
selector: "bit-disclosure", | ||
standalone: true, | ||
template: `<ng-content></ng-content>`, | ||
}) | ||
export class DisclosureComponent { | ||
/** | ||
* Optionally init the disclosure in its opened state | ||
*/ | ||
@Input({ transform: booleanAttribute }) open?: boolean = false; | ||
|
||
@HostBinding("class") get classList() { | ||
return this.open ? "" : "tw-hidden"; | ||
} | ||
|
||
@HostBinding("id") id = `bit-disclosure-${nextId++}`; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; | ||
|
||
import * as stories from "./disclosure.stories"; | ||
|
||
<Meta of={stories} /> | ||
|
||
```ts | ||
import { DisclosureComponent, DisclosureTriggerForDirective } from "@bitwarden/components"; | ||
``` | ||
|
||
# Disclosure | ||
|
||
The `bit-disclosure` component is used in tandem with the `bitDisclosureTriggerFor` directive to | ||
create an accessible content area whose visibility is controlled by a trigger button. | ||
|
||
To compose a disclosure and trigger: | ||
|
||
1. Create a trigger component (see "Supported Trigger Components" section below) | ||
2. Create a `bit-disclosure` | ||
3. Set a template reference on the `bit-disclosure` | ||
4. Use the `bitDisclosureTriggerFor` directive on the trigger component, and pass it the | ||
`bit-disclosure` template reference | ||
5. Set the `open` property on the `bit-disclosure` to init the disclosure as either currently | ||
expanded or currently collapsed. The disclosure will default to `false`, meaning it defaults to | ||
being hidden. | ||
|
||
``` | ||
<button | ||
type="button" | ||
bitIconButton="bwi-sliders" | ||
[buttonType]="'muted'" | ||
[bitDisclosureTriggerFor]="disclosureRef" | ||
></button> | ||
<bit-disclosure #disclosureRef open>click button to hide this content</bit-disclosure> | ||
``` | ||
|
||
<Story of={stories.DisclosureWithIconButton} /> | ||
|
||
<br /> | ||
<br /> | ||
|
||
## Supported Trigger Components | ||
|
||
This is the list of currently supported trigger components: | ||
|
||
- Icon button `muted` variant | ||
|
||
## Accessibility | ||
|
||
The disclosure and trigger directive functionality follow the | ||
[Disclosure (Show/Hide)](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/) pattern for | ||
accessibility, automatically handling the `aria-controls` and `aria-expanded` properties. A `button` | ||
element must be used as the trigger for the disclosure. The `button` element must also have an | ||
accessible label/title -- please follow the accessibility guidelines for whatever trigger component | ||
you choose. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { Meta, moduleMetadata, StoryObj } from "@storybook/angular"; | ||
|
||
import { IconButtonModule } from "../icon-button"; | ||
|
||
import { DisclosureTriggerForDirective } from "./disclosure-trigger-for.directive"; | ||
import { DisclosureComponent } from "./disclosure.component"; | ||
|
||
export default { | ||
title: "Component Library/Disclosure", | ||
component: DisclosureComponent, | ||
decorators: [ | ||
moduleMetadata({ | ||
imports: [DisclosureTriggerForDirective, DisclosureComponent, IconButtonModule], | ||
}), | ||
], | ||
} as Meta<DisclosureComponent>; | ||
|
||
type Story = StoryObj<DisclosureComponent>; | ||
|
||
export const DisclosureWithIconButton: Story = { | ||
render: (args) => ({ | ||
props: args, | ||
template: /*html*/ ` | ||
<button type="button" bitIconButton="bwi-sliders" [buttonType]="'muted'" [bitDisclosureTriggerFor]="disclosureRef"> | ||
</button> | ||
<bit-disclosure #disclosureRef class="tw-text-main tw-block" open>click button to hide this content</bit-disclosure> | ||
`, | ||
}), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./disclosure-trigger-for.directive"; | ||
export * from "./disclosure.component"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters