diff --git a/src/app/playground-components.ts b/src/app/playground-components.ts
index 84d5261097..a97497f4d2 100644
--- a/src/app/playground-components.ts
+++ b/src/app/playground-components.ts
@@ -69,6 +69,12 @@ export const PLAYGROUND_COMPONENTS: ComponentLink[] = [
component: 'ActionWidthComponent',
name: 'Action Width',
},
+ {
+ path: 'action-dot-mode.component',
+ link: '/action/action-dot-mode.component',
+ component: 'ActionDotModeComponent',
+ name: 'Action Dot Mode',
+ },
],
},
{
@@ -724,6 +730,12 @@ export const PLAYGROUND_COMPONENTS: ComponentLink[] = [
component: 'MenuLinkParamsComponent',
name: 'Menu Link Params',
},
+ {
+ path: 'menu-badge.component',
+ link: '/menu/menu-badge.component',
+ component: 'MenuBadgeComponent',
+ name: 'Menu Badge',
+ },
{
path: 'menu-service.component',
link: '/menu/menu-service.component',
diff --git a/src/framework/theme/components/actions/_actions.component.theme.scss b/src/framework/theme/components/actions/_actions.component.theme.scss
index 6ab78171c1..c18cb204c5 100644
--- a/src/framework/theme/components/actions/_actions.component.theme.scss
+++ b/src/framework/theme/components/actions/_actions.component.theme.scss
@@ -25,14 +25,15 @@
}
}
+
nb-action {
$divider: nb-theme(actions-divider-width) nb-theme(actions-divider-style) nb-theme(actions-divider-color);
@include nb-ltr(border-left, $divider);
@include nb-rtl(border-right, $divider);
&:first-child {
- @include nb-ltr(border-left, none!important);
- @include nb-rtl(border-right, none!important);
+ @include nb-ltr(border-left, none !important);
+ @include nb-rtl(border-right, none !important);
}
nb-icon {
diff --git a/src/framework/theme/components/actions/action.component.scss b/src/framework/theme/components/actions/action.component.scss
index e41747df64..3e12cccefb 100644
--- a/src/framework/theme/components/actions/action.component.scss
+++ b/src/framework/theme/components/actions/action.component.scss
@@ -25,6 +25,8 @@
}
a.icon-container {
+ position: relative;
+
&:hover, &:focus {
text-decoration: none;
}
diff --git a/src/framework/theme/components/actions/actions.component.ts b/src/framework/theme/components/actions/actions.component.ts
index d4580bb667..0cb9ea9cfd 100644
--- a/src/framework/theme/components/actions/actions.component.ts
+++ b/src/framework/theme/components/actions/actions.component.ts
@@ -25,12 +25,14 @@ import { NbIconConfig } from '../icon/icon.component';
[title]="title"
*ngIf="link">
+
+
+
+
+
+
+
+
-
-
-
`,
})
export class NbActionComponent {
@@ -93,6 +99,20 @@ export class NbActionComponent {
protected _disabled: boolean = false;
static ngAcceptInputType_disabled: NbBooleanInput;
+ /**
+ * Use badge dot mode
+ * @type boolean
+ */
+ @Input()
+ get badgeDot(): boolean {
+ return this._badgeDot;
+ }
+ set badgeDot(value: boolean) {
+ this._badgeDot = convertToBoolProperty(value);
+ }
+ protected _badgeDot: boolean;
+ static ngAcceptInputType_badgeDot: NbBooleanInput;
+
/**
* Badge text to display
* @type string
@@ -154,6 +174,9 @@ export class NbActionComponent {
* and we can set it to full a width of a parent component
* @stacked-example(Full Width, action/action-width.component)
*
+ * Action dot mode
+ * @stacked-example(Action badge in dot mode, action/action-dot-mode.component)
+ *
* @styles
*
* actions-background-color:
diff --git a/src/framework/theme/components/badge/_badge.component.theme.scss b/src/framework/theme/components/badge/_badge.component.theme.scss
index 390ff7af3a..1ca87df9cb 100644
--- a/src/framework/theme/components/badge/_badge.component.theme.scss
+++ b/src/framework/theme/components/badge/_badge.component.theme.scss
@@ -12,6 +12,11 @@
font-weight: nb-theme(badge-text-font-weight);
line-height: nb-theme(badge-text-line-height);
padding: nb-theme(badge-padding);
+
+ &.dot-mode {
+ padding: nb-theme(badge-dot-mode-padding);
+ border-radius: nb-theme(badge-dot-mode-border-radius);
+ }
}
@each $status in nb-get-statuses() {
diff --git a/src/framework/theme/components/badge/badge.component.scss b/src/framework/theme/components/badge/badge.component.scss
index eb46dc3910..c079c09a0a 100644
--- a/src/framework/theme/components/badge/badge.component.scss
+++ b/src/framework/theme/components/badge/badge.component.scss
@@ -29,6 +29,11 @@
left: 0;
}
+:host(.position-center) {
+ top: 50%;
+ transform: translateY(-50%);
+}
+
:host(.position-start) {
@include nb-ltr(left, 0);
@include nb-rtl(right, 0);
diff --git a/src/framework/theme/components/badge/badge.component.ts b/src/framework/theme/components/badge/badge.component.ts
index ce96210b83..ffdc3a29be 100644
--- a/src/framework/theme/components/badge/badge.component.ts
+++ b/src/framework/theme/components/badge/badge.component.ts
@@ -7,12 +7,18 @@
import { Component, HostBinding, Input } from '@angular/core';
import { NbComponentStatus } from '../component-status';
-import { emptyStatusWarning } from '../helpers';
+import { convertToBoolProperty, emptyStatusWarning } from '../helpers';
-export type NbBadgePhysicalPosition = 'top left' | 'top right' | 'bottom left' | 'bottom right';
-export type NbBadgeLogicalPosition = 'top start' | 'top end' | 'bottom start' | 'bottom end';
+export type NbBadgePhysicalPosition = 'top left' | 'top right' | 'bottom left' | 'bottom right' | 'center right' | 'center left';
+export type NbBadgeLogicalPosition = 'top start' | 'top end' | 'bottom start' | 'bottom end' | 'center start'| 'center end';
export type NbBadgePosition = NbBadgePhysicalPosition | NbBadgeLogicalPosition;
+export interface NbBadge {
+ text?: string;
+ position?: NbBadgePosition;
+ status?: NbComponentStatus;
+ dotMode?: boolean;
+}
/**
* Badge is a simple labeling component.
@@ -79,9 +85,9 @@ export type NbBadgePosition = NbBadgePhysicalPosition | NbBadgeLogicalPosition;
@Component({
selector: 'nb-badge',
styleUrls: ['./badge.component.scss'],
- template: `{{text}}`,
+ template: `{{dotMode ? '' : text}}`,
})
-export class NbBadgeComponent {
+export class NbBadgeComponent implements NbBadge {
/**
* Text to display
@@ -107,6 +113,20 @@ export class NbBadgeComponent {
protected _defaultPosition: NbBadgePosition = 'top right';
protected _position: NbBadgePosition = this._defaultPosition;
+ /**
+ * Shows badge as a dot. No text is shown.
+ * @type boolean
+ */
+ @Input()
+ @HostBinding('class.dot-mode')
+ get dotMode(): boolean {
+ return this._dotMode;
+ }
+ set dotMode(value: boolean) {
+ this._dotMode = convertToBoolProperty(value);
+ }
+ protected _dotMode: boolean;
+
/**
* Badge status (adds specific styles):
* 'basic', 'primary', 'info', 'success', 'warning', 'danger', 'control'
@@ -188,4 +208,9 @@ export class NbBadgeComponent {
get end(): boolean {
return this.position.includes('end');
}
+
+ @HostBinding('class.position-center')
+ get center(): boolean {
+ return this.position.includes('center');
+ }
}
diff --git a/src/framework/theme/components/menu/menu-item.component.html b/src/framework/theme/components/menu/menu-item.component.html
index a828f9bc6e..58f32582f1 100644
--- a/src/framework/theme/components/menu/menu-item.component.html
+++ b/src/framework/theme/components/menu/menu-item.component.html
@@ -14,6 +14,7 @@
(click)="onItemClick(menuItem);">
+
+
+
+
+
+
+
+
+
diff --git a/src/framework/theme/components/menu/menu.component.scss b/src/framework/theme/components/menu/menu.component.scss
index 174a3e8f4e..e35c30e3e4 100644
--- a/src/framework/theme/components/menu/menu.component.scss
+++ b/src/framework/theme/components/menu/menu.component.scss
@@ -26,6 +26,10 @@
}
}
+ .menu-item nb-badge {
+ position: static;
+ }
+
.menu-group span {
display: flex;
}
diff --git a/src/framework/theme/components/menu/menu.component.ts b/src/framework/theme/components/menu/menu.component.ts
index 246eccf021..2e5ac73832 100644
--- a/src/framework/theme/components/menu/menu.component.ts
+++ b/src/framework/theme/components/menu/menu.component.ts
@@ -20,7 +20,7 @@ import { isPlatformBrowser } from '@angular/common';
import { Router, NavigationEnd } from '@angular/router';
import { BehaviorSubject, Subject } from 'rxjs';
import { takeUntil, filter, map } from 'rxjs/operators';
-import { NbMenuInternalService, NbMenuItem, NbMenuBag, NbMenuService } from './menu.service';
+import { NbMenuInternalService, NbMenuItem, NbMenuBag, NbMenuService, NbMenuBadgeConfig } from './menu.service';
import { convertToBoolProperty, NbBooleanInput } from '../helpers';
import { NB_WINDOW } from '../../theme.options';
import { animate, state, style, transition, trigger } from '@angular/animations';
@@ -44,6 +44,7 @@ export enum NbToggleStates {
})
export class NbMenuItemComponent implements DoCheck, AfterViewInit, OnDestroy {
@Input() menuItem = null;
+ @Input() badge: NbMenuBadgeConfig;
@Output() hoverItem = new EventEmitter();
@Output() toggleSubMenu = new EventEmitter();
@@ -156,6 +157,8 @@ export class NbMenuItemComponent implements DoCheck, AfterViewInit, OnDestroy {
* Autocollapse menu example
* @stacked-example(Autocollapse Menu, menu/menu-autocollapse.component)
*
+ * Menu badge
+ * @stacked-example(Menu item badge, menu/menu-badge.component)
*
* @styles
*
@@ -211,6 +214,7 @@ export class NbMenuItemComponent implements DoCheck, AfterViewInit, OnDestroy {
(1);
const submenuToggle$ = new ReplaySubject(1);
const collapseAll$ = new ReplaySubject<{ tag: string }>(1);
+export type NbMenuBadgeConfig = Omit;
+
// TODO: check if we need both URL and LINK
/**
*
@@ -59,6 +62,11 @@ export class NbMenuItem {
* @type {boolean}
*/
expanded?: boolean;
+ /**
+ * Badge component
+ * @type {boolean}
+ */
+ badge?: NbMenuBadgeConfig;
/**
* Children items
* @type {List}
diff --git a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss
index 7774a817f1..ac0d2053de 100644
--- a/src/framework/theme/components/sidebar/_sidebar.component.theme.scss
+++ b/src/framework/theme/components/sidebar/_sidebar.component.theme.scss
@@ -84,7 +84,7 @@
}
> .menu-items > .menu-item > a {
- span, .expand-state {
+ span, nb-badge, .expand-state {
display: none;
}
}
diff --git a/src/framework/theme/components/tabset/_tabset.component.theme.scss b/src/framework/theme/components/tabset/_tabset.component.theme.scss
index 63976042e5..26ff0d4c67 100644
--- a/src/framework/theme/components/tabset/_tabset.component.theme.scss
+++ b/src/framework/theme/components/tabset/_tabset.component.theme.scss
@@ -32,6 +32,24 @@
}
}
+ nb-badge.dot-mode.position-left {
+ left: nb-theme(tabset-tab–badge-dot-mode-horizontal-offset);
+ }
+
+ nb-badge.dot-mode.position-right {
+ right: nb-theme(tabset-tab–badge-dot-mode-horizontal-offset);
+ }
+
+ nb-badge.dot-mode.position-start {
+ @include nb-ltr(left, nb-theme(tabset-tab–badge-dot-mode-horizontal-offset));
+ @include nb-rtl(right, nb-theme(tabset-tab–badge-dot-mode-horizontal-offset));
+ }
+
+ nb-badge.dot-mode.position-end {
+ @include nb-ltr(right, nb-theme(tabset-tab–badge-dot-mode-horizontal-offset));
+ @include nb-rtl(left, nb-theme(tabset-tab–badge-dot-mode-horizontal-offset));
+ }
+
.tab.active {
.tab-link {
background-color: nb-theme(tabset-tab-active-background-color);
diff --git a/src/framework/theme/components/tabset/tabset.component.ts b/src/framework/theme/components/tabset/tabset.component.ts
index be07007270..ec3bd7ed1e 100644
--- a/src/framework/theme/components/tabset/tabset.component.ts
+++ b/src/framework/theme/components/tabset/tabset.component.ts
@@ -56,6 +56,20 @@ export class NbTabComponent {
*/
@Input() tabId: string;
+ /**
+ * Use badge dot mode
+ * @type {boolean}
+ */
+ @Input()
+ get badgeDot(): boolean {
+ return this._badgeDot;
+ }
+ set badgeDot(val: boolean) {
+ this._badgeDot = convertToBoolProperty(val);
+ }
+ protected _badgeDot: boolean;
+ static ngAcceptInputType_badgeDot: NbBooleanInput;
+
/**
* Tab icon name or icon config object
* @type {string | NbIconConfig}
@@ -261,8 +275,9 @@ export class NbTabComponent {
{{ tab.tabTitle }}
-
diff --git a/src/framework/theme/styles/themes/_mapping.scss b/src/framework/theme/styles/themes/_mapping.scss
index 7c8343084f..15d9183d61 100644
--- a/src/framework/theme/styles/themes/_mapping.scss
+++ b/src/framework/theme/styles/themes/_mapping.scss
@@ -204,6 +204,8 @@ $eva-mapping: (
tabset-tab-disabled-background-color: transparent,
tabset-tab-disabled-text-color: text-disabled-color,
tabset-tab-disabled-underline-color: transparent,
+ tabset-tab–badge-dot-mode-horizontal-offset: 0.75rem,
+ tabset-tab-badge-dot-mode-padding: 0.25rem,
tabset-divider-color: divider-color,
tabset-divider-style: divider-style,
@@ -1392,6 +1394,9 @@ $eva-mapping: (
checkbox-control-disabled-checked-background-color: color-basic-transparent-600,
checkbox-control-disabled-checked-border-color: color-basic-transparent-600,
+ badge-dot-mode-border-radius: 0.5rem,
+ badge-dot-mode-padding: 0.3rem,
+
badge-border-radius: border-radius,
badge-text-font-family: text-button-font-family,
badge-text-font-size: text-button-tiny-font-size,
diff --git a/src/playground/with-layout/action/action-dot-mode.component.html b/src/playground/with-layout/action/action-dot-mode.component.html
new file mode 100644
index 0000000000..a0535dac30
--- /dev/null
+++ b/src/playground/with-layout/action/action-dot-mode.component.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/playground/with-layout/action/action-dot-mode.component.ts b/src/playground/with-layout/action/action-dot-mode.component.ts
new file mode 100644
index 0000000000..d58fb3e5df
--- /dev/null
+++ b/src/playground/with-layout/action/action-dot-mode.component.ts
@@ -0,0 +1,15 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ */
+
+import { ChangeDetectionStrategy, Component } from '@angular/core';
+
+@Component({
+ selector: 'nb-action-dot-mode',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ templateUrl: './action-dot-mode.component.html',
+})
+export class ActionDotModeComponent {
+}
diff --git a/src/playground/with-layout/action/action-routing.module.ts b/src/playground/with-layout/action/action-routing.module.ts
index eed2f5d22a..3b1d9bcde2 100644
--- a/src/playground/with-layout/action/action-routing.module.ts
+++ b/src/playground/with-layout/action/action-routing.module.ts
@@ -11,6 +11,7 @@ import { ActionShowcaseComponent } from './action-showcase.component';
import { ActionSizesComponent } from './action-sizes.component';
import { ActionTestComponent } from './action-test.component';
import { ActionWidthComponent } from './action-width.component';
+import { ActionDotModeComponent } from './action-dot-mode.component';
const routes: Route[] = [
{
@@ -33,6 +34,10 @@ const routes: Route[] = [
path: 'action-width.component',
component: ActionWidthComponent,
},
+ {
+ path: 'action-dot-mode.component',
+ component: ActionDotModeComponent,
+ },
];
@NgModule({
diff --git a/src/playground/with-layout/action/action.module.ts b/src/playground/with-layout/action/action.module.ts
index bfdf1ed9c9..62cdee3b53 100644
--- a/src/playground/with-layout/action/action.module.ts
+++ b/src/playground/with-layout/action/action.module.ts
@@ -13,6 +13,7 @@ import { ActionShowcaseComponent } from './action-showcase.component';
import { ActionSizesComponent } from './action-sizes.component';
import { ActionTestComponent } from './action-test.component';
import { ActionWidthComponent } from './action-width.component';
+import { ActionDotModeComponent } from './action-dot-mode.component';
@NgModule({
declarations: [
@@ -21,6 +22,7 @@ import { ActionWidthComponent } from './action-width.component';
ActionSizesComponent,
ActionTestComponent,
ActionWidthComponent,
+ ActionDotModeComponent,
],
imports: [
NbActionsModule,
diff --git a/src/playground/with-layout/menu/menu-badge.component.html b/src/playground/with-layout/menu/menu-badge.component.html
new file mode 100644
index 0000000000..eec714cb88
--- /dev/null
+++ b/src/playground/with-layout/menu/menu-badge.component.html
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/src/playground/with-layout/menu/menu-badge.component.scss b/src/playground/with-layout/menu/menu-badge.component.scss
new file mode 100644
index 0000000000..df57c265c8
--- /dev/null
+++ b/src/playground/with-layout/menu/menu-badge.component.scss
@@ -0,0 +1,9 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ */
+
+nb-card {
+ width: 20rem;
+}
diff --git a/src/playground/with-layout/menu/menu-badge.component.ts b/src/playground/with-layout/menu/menu-badge.component.ts
new file mode 100644
index 0000000000..cd9ac737b6
--- /dev/null
+++ b/src/playground/with-layout/menu/menu-badge.component.ts
@@ -0,0 +1,51 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ */
+
+import { ChangeDetectionStrategy, Component } from '@angular/core';
+import { NbMenuItem } from '@nebular/theme';
+
+@Component({
+ selector: 'nb-menu-badge',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ templateUrl: './menu-badge.component.html',
+ styleUrls: ['./menu-badge.component.scss'],
+})
+export class MenuBadgeComponent {
+
+ items: NbMenuItem[] = [
+ {
+ title: 'Profile',
+ expanded: true,
+ badge: {
+ text: '30',
+ status: 'primary',
+ },
+ children: [
+ {
+ title: 'Messages',
+ badge: {
+ text: '99+',
+ status: 'danger',
+ },
+ },
+ {
+ title: 'Notifications',
+ badge: {
+ dotMode: true,
+ status: 'warning',
+ },
+ },
+ {
+ title: 'Emails',
+ badge: {
+ text: 'new',
+ status: 'success',
+ },
+ },
+ ],
+ },
+ ];
+}
diff --git a/src/playground/with-layout/menu/menu-routing.module.ts b/src/playground/with-layout/menu/menu-routing.module.ts
index 861d8236ea..9a1d61bd9f 100644
--- a/src/playground/with-layout/menu/menu-routing.module.ts
+++ b/src/playground/with-layout/menu/menu-routing.module.ts
@@ -21,6 +21,7 @@ import {
MenuServiceItem3Component,
} from './menu-service-children';
import { MenuServiceComponent } from './menu-service.component';
+import { MenuBadgeComponent } from './menu-badge.component';
const routes: Route[] = [
{
@@ -39,6 +40,10 @@ const routes: Route[] = [
path: 'menu-link-params.component',
component: MenuLinkParamsComponent,
},
+ {
+ path: 'menu-badge.component',
+ component: MenuBadgeComponent,
+ },
{
path: 'menu-service.component',
component: MenuServiceComponent,
diff --git a/src/playground/with-layout/menu/menu.module.ts b/src/playground/with-layout/menu/menu.module.ts
index a5fdcf96fe..0572034148 100644
--- a/src/playground/with-layout/menu/menu.module.ts
+++ b/src/playground/with-layout/menu/menu.module.ts
@@ -22,6 +22,7 @@ import {
MenuServiceItem332Component,
} from './menu-service-children';
import { MenuServiceComponent } from './menu-service.component';
+import { MenuBadgeComponent } from './menu-badge.component';
@NgModule({
declarations: [
@@ -38,6 +39,7 @@ import { MenuServiceComponent } from './menu-service.component';
MenuServiceItem331Component,
MenuServiceItem332Component,
MenuServiceComponent,
+ MenuBadgeComponent,
],
imports: [
NbMenuModule.forRoot(),
diff --git a/src/playground/with-layout/tabset/tabset-badge.component.html b/src/playground/with-layout/tabset/tabset-badge.component.html
index 540d6c611e..f3f428f977 100644
--- a/src/playground/with-layout/tabset/tabset-badge.component.html
+++ b/src/playground/with-layout/tabset/tabset-badge.component.html
@@ -19,6 +19,12 @@
badgeStatus="success">
List of transactions.
+
+ List of notifications.
+