Skip to content

Commit

Permalink
Banner component (#1036)
Browse files Browse the repository at this point in the history
# Pull Request

## 🀨 Rationale

See #305 

## πŸ‘©β€πŸ’» Implementation

- Created new banner component (not based on FAST)
- Added unit tests and visual Storybook tests
- Updated README

## πŸ§ͺ Testing

Unit tests and Storybook testing

## βœ… Checklist

- [x] I have updated the project documentation to reflect my changes or
determined no changes are needed.

---------

Co-authored-by: mollykreis <20542556+mollykreis@users.noreply.github.com>
  • Loading branch information
m-akinc and mollykreis authored Feb 15, 2023
1 parent 28a5610 commit 0248f3d
Show file tree
Hide file tree
Showing 15 changed files with 792 additions and 6 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ NOTE: To update the component status:
| Accordion | | [Issue](https://github.com/ni/nimble/issues/533) | :o: | :o: | :o: |
| Anchor | [XD](https://xd.adobe.com/view/33ffad4a-eb2c-4241-b8c5-ebfff1faf6f6-66ac/screen/bfadf499-caf5-4ca0-9814-e777fbae0d46/) | [Issue](https://github.com/ni/nimble/issues/324) | [:white_check_mark: - SB](https://ni.github.io/nimble/storybook/?path=/docs/anchor--text-anchor) | :white_check_mark: | :white_check_mark: |
| Anchor Button | | [Issue](https://github.com/ni/nimble/issues/324) | [:white_check_mark: - SB](https://ni.github.io/nimble/storybook/?path=/docs/anchor-button--outline-anchor-button) | :white_check_mark: | :white_check_mark: |
| Anchor Tabs | [XD](https://xd.adobe.com/view/33ffad4a-eb2c-4241-b8c5-ebfff1faf6f6-66ac/screen/b2aa2c0c-03b7-4571-8e0d-de88baf0814b) | [Issue](https://github.com/ni/nimble/issues/479) | [:white_check_mark: - SB](https://nimble.ni.dev/storybook/?path=/docs/anchor-tabs--tabs) | :white_check_mark: | :white_check_mark: |
| Banners | [XD](https://xd.adobe.com/view/33ffad4a-eb2c-4241-b8c5-ebfff1faf6f6-66ac/screen/29c405f7-08ea-48b6-973f-546970b9dbab) | [Issue](https://github.com/ni/nimble/issues/305) | :o: | :o: | :o: |
| Anchor Tabs | [XD](https://xd.adobe.com/view/33ffad4a-eb2c-4241-b8c5-ebfff1faf6f6-66ac/screen/b2aa2c0c-03b7-4571-8e0d-de88baf0814b) | [Issue](https://github.com/ni/nimble/issues/479) | [:white_check_mark: - SB](https://nimble.ni.dev/storybook/?path=/docs/anchor-tabs--anchor-tabs) | :white_check_mark: | :white_check_mark: |
| Banner | [XD](https://xd.adobe.com/view/33ffad4a-eb2c-4241-b8c5-ebfff1faf6f6-66ac/screen/29c405f7-08ea-48b6-973f-546970b9dbab) | [Issue](https://github.com/ni/nimble/issues/305) | [:white_check_mark: - SB](https://nimble.ni.dev/storybook/?path=/docs/banner--banner) | :o: | :o: |
| Breadcrumb | [XD](https://xd.adobe.com/view/33ffad4a-eb2c-4241-b8c5-ebfff1faf6f6-66ac/screen/7b53bb3e-439b-4f13-9d5f-55adc7da8a2e) | | [:white_check_mark: - SB](https://ni.github.io/nimble/storybook/?path=/docs/breadcrumb--standard-breadcrumb) | :white_check_mark: | :white_check_mark: |
| Card | | [Issue](https://github.com/ni/nimble/issues/296) | :o: | :o: | :o: |
| Card button | [XD](https://xd.adobe.com/view/33ffad4a-eb2c-4241-b8c5-ebfff1faf6f6-66ac/screen/d4ebeb5d-023c-4ff2-a71c-f6385fffca20) | [Issue](https://github.com/ni/nimble/issues/643) | [:white_check_mark: - SB](https://ni.github.io/nimble/storybook/?path=/docs/card-button--card-button) | :white_check_mark: | :white_check_mark: |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Banner component",
"packageName": "@ni/nimble-components",
"email": "7282195+m-akinc@users.noreply.github.com",
"dependentChangeType": "patch"
}
13 changes: 13 additions & 0 deletions packages/nimble-components/docs/coding-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,17 @@ To clients, the object and values will behave like an enum:
```ts
import { ButtonAppearance from '../types.ts' }
let appearance: ButtonAppearance = ButtonAppearance.outline;
```
## Default enum values
If one of the enum values represents a default, it should be named `default` and be the first enumerated value.
```ts
export const BannerSeverity = {
default: undefined,
error: 'error',
warning: 'warning',
information: 'information'
} as const;
```
1 change: 1 addition & 0 deletions packages/nimble-components/src/all-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import './anchor-button';
import './anchor-tab';
import './anchor-tabs';
import './anchored-region';
import './banner';
import './breadcrumb';
import './breadcrumb-item';
import './button';
Expand Down
87 changes: 87 additions & 0 deletions packages/nimble-components/src/banner/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { attr } from '@microsoft/fast-element';
import {
applyMixins,
ARIAGlobalStatesAndProperties,
DesignSystem,
FoundationElement
} from '@microsoft/fast-foundation';
import { styles } from './styles';
import { template } from './template';
import { BannerSeverity } from './types';

declare global {
interface HTMLElementTagNameMap {
'nimble-banner': Banner;
}
}

/**
* A nimble-styled notification banner for persistent messages.
*/
export class Banner extends FoundationElement {
/**
* @public
* @description
* Whether the banner is visible or not
*/
@attr({ mode: 'boolean' })
public open = false;

/**
* @public
* @description
* Severity of the banner's message
*/
@attr()
public severity: BannerSeverity = BannerSeverity.default;

/**
* @public
* @description
* Whether the banner title is hidden
*/
@attr({ attribute: 'title-hidden', mode: 'boolean' })
public titleHidden = false;

/**
* @public
* @description
* Hides the dismiss button
*/
@attr({ attribute: 'prevent-dismiss', mode: 'boolean' })
public preventDismiss = false;

/**
* @public
* @description
* Label (not visible) for the dismiss button
*/
@attr({ attribute: 'dismiss-button-label' })
public dismissButtonLabel?: string;

/**
* @internal
*/
public openChanged(): void {
this.$emit('toggle', { oldState: !this.open, newState: this.open });
}

/**
* @internal
*/
public dismissBanner(): void {
this.open = false;
}
}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface Banner extends ARIAGlobalStatesAndProperties {}
applyMixins(Banner, ARIAGlobalStatesAndProperties);

const nimbleBanner = Banner.compose({
baseName: 'banner',
template,
styles
});

DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleBanner());
213 changes: 213 additions & 0 deletions packages/nimble-components/src/banner/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import { css } from '@microsoft/fast-element';
import { display } from '@microsoft/fast-foundation';
import {
BannerFail100DarkUi,
Black75,
Fail100LightUi,
Information100DarkUi,
Information100LightUi,
Warning100DarkUi,
Warning100LightUi,
White
} from '@ni/nimble-tokens/dist/styledictionary/js/tokens';

import {
actionRgbPartialColor,
applicationBackgroundColor,
bodyFont,
borderHoverColor,
buttonLabelFontColor,
controlHeight,
controlSlimHeight,
fillSelectedColor,
iconColor,
iconSize,
linkActiveFontColor,
linkDisabledFontColor,
linkFontColor,
standardPadding
} from '../theme-provider/design-tokens';
import { Theme } from '../theme-provider/types';
import { hexToRgbaCssColor } from '../utilities/style/colors';
import { themeBehavior } from '../utilities/style/theme';

export const styles = css`
${display('flex')}
:host {
font: ${bodyFont};
font-size: 12.8px;
align-items: top;
overflow: hidden;
color: ${White};
${iconColor.cssCustomProperty}: ${hexToRgbaCssColor(White, 0.6)};
}
:host(:not([open])) {
display: none;
}
.container {
display: flex;
width: 100%;
}
.icon {
width: 48px;
display: flex;
justify-content: center;
margin-top: 8px;
flex: 0 0 auto;
}
.text {
display: inline;
margin-top: 7px;
margin-bottom: 7px;
}
slot[name='title'] {
display: inline;
font-weight: bold;
padding-right: 8px;
white-space: nowrap;
}
:host([title-hidden]) slot[name='title'] {
${
/**
* Hide content visually while keeping it screen reader-accessible.
* Source: https://webaim.org/techniques/css/invisiblecontent/#techniques
* See discussion here: https://github.com/microsoft/fast/issues/5740#issuecomment-1068195035
*/
''
}
display: inline-block;
height: 1px;
width: 1px;
position: absolute;
margin: -1px;
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
overflow: hidden;
padding: 0;
}
.controls {
height: ${controlHeight};
margin-left: auto;
display: flex;
align-items: center;
justify-content: center;
align-self: flex-start;
}
slot[name='action'] {
display: flex;
align-content: center;
margin-left: ${standardPadding};
white-space: nowrap;
}
slot[name='action']::slotted(nimble-anchor) {
${linkFontColor.cssCustomProperty}: ${White};
${linkDisabledFontColor.cssCustomProperty}: ${White};
${linkActiveFontColor.cssCustomProperty}: ${hexToRgbaCssColor(
White,
0.6
)};
font-size: 12.8px;
}
slot[name='action']::slotted(nimble-button) {
${controlHeight.cssCustomProperty}: ${controlSlimHeight};
${buttonLabelFontColor.cssCustomProperty}: ${White};
${fillSelectedColor.cssCustomProperty}: ${hexToRgbaCssColor(
White,
0.2
)};
${borderHoverColor.cssCustomProperty}: ${White};
}
slot[name='action']::slotted(nimble-button[appearance='outline']) {
${actionRgbPartialColor.cssCustomProperty}: ${White}
}
.dismiss {
width: 48px;
display: flex;
justify-content: center;
}
.dismiss nimble-button {
${controlHeight.cssCustomProperty}: 16px;
${iconSize.cssCustomProperty}: 14px;
${buttonLabelFontColor.cssCustomProperty}: ${White};
${borderHoverColor.cssCustomProperty}: transparent;
${fillSelectedColor.cssCustomProperty}: ${hexToRgbaCssColor(
White,
0.2
)};
}
.dismiss nimble-button:focus-within {
outline: 2px solid ${White};
}
.dismiss nimble-button:hover {
background: ${hexToRgbaCssColor(White, 0.2)};
}
`.withBehaviors(
themeBehavior(
Theme.light,
css`
:host {
background: ${Black75};
}
:host([severity='error']) {
background: ${Fail100LightUi};
}
:host([severity='warning']) {
background: ${Warning100LightUi};
}
:host([severity='information']) {
background: ${Information100LightUi};
}
`
),
themeBehavior(
Theme.dark,
css`
:host {
background: ${Black75};
}
:host([severity='error']) {
background: ${BannerFail100DarkUi};
}
:host([severity='warning']) {
background: ${Warning100DarkUi};
}
:host([severity='information']) {
background: ${Information100DarkUi};
}
`
),
themeBehavior(
Theme.color,
css`
:host {
background: ${applicationBackgroundColor};
}
.container {
background: ${hexToRgbaCssColor(White, 0.3)};
}
`
)
);
Loading

0 comments on commit 0248f3d

Please sign in to comment.