SelectModule,
ComboBoxModule,
ProgressIndicatorModule,
- PanelModule
+ PanelModule,
+ LayoutModule
} from 'carbon-components-angular';
import EditIcon from '@carbon/icons/es/edit/20';
import CodeIcon from '@carbon/icons/es/code/16';
import { UpgradableComponent } from './upgradable/upgradable.component';
import { ProgressComponent } from './progress/progress.component';
import { SidePanelComponent } from './side-panel/side-panel.component';
+import { ChartsModule } from '@carbon/charts-angular';
+import { InlineMessageComponent } from './inline-message/inline-message.component';
+import { IconComponent } from './icon/icon.component';
// Icons
import InfoIcon from '@carbon/icons/es/information/16';
import CopyIcon from '@carbon/icons/es/copy/32';
import downloadIcon from '@carbon/icons/es/download/16';
-import { ChartsModule } from '@carbon/charts-angular';
-import { IconComponent } from './icon/icon.component';
+import IdeaIcon from '@carbon/icons/es/idea/20';
+import CloseIcon from '@carbon/icons/es/close/16';
@NgModule({
imports: [
ProgressIndicatorModule,
BaseChartDirective,
PanelModule,
- ChartsModule
+ ChartsModule,
+ LayoutModule
],
declarations: [
SparklineComponent,
UpgradableComponent,
ProgressComponent,
SidePanelComponent,
- IconComponent
+ IconComponent,
+ InlineMessageComponent
],
providers: [provideCharts(withDefaultRegisterables())],
exports: [
UpgradableComponent,
ProgressComponent,
SidePanelComponent,
- IconComponent
+ IconComponent,
+ InlineMessageComponent
]
})
export class ComponentsModule {
constructor(private iconService: IconService) {
- this.iconService.registerAll([InfoIcon, CopyIcon, EditIcon, CodeIcon, downloadIcon]);
+ this.iconService.registerAll([
+ InfoIcon,
+ CopyIcon,
+ EditIcon,
+ CodeIcon,
+ downloadIcon,
+ IdeaIcon,
+ CloseIcon
+ ]);
}
}
--- /dev/null
+@if (!isDismissed) {
+ <div class="inline-tip-container"
+ [cdsStack]="'horizontal'"
+ [gap]="4">
+ <div class="close-btn-position">
+ <cds-icon-button class="close-btn inline-tip-bg-color"
+ type="button"
+ kind="ghost"
+ size="sm"
+ description="Close"
+ i18n-description
+ (click)="close()">
+ <svg [size]="icons.size16"
+ [cdsIcon]="icons.destroy"></svg>
+ </cds-icon-button>
+ </div>
+
+ <div class="inline-tip-body"
+ [cdsStack]="'horizontal'"
+ [gap]="4">
+ <svg [cdsIcon]="icons.idea"
+ [size]="icons.size20"></svg>
+
+ <div [cdsStack]="'vertical'"
+ [gap]="1"
+ class="inline-tip-body-content">
+ @if (title) {
+ <h1 class="cds--type-heading-compact-01">{{ title }}</h1>
+ }
+
+ <div class="cds--type-body-compact-01"
+ [class.cds--text-truncate--end]="isTruncated">
+ <ng-content></ng-content>
+ </div>
+ @if (collapsible) {
+ <button class="inline-tip-bg-color btn-toggle"
+ cdsButton="ghost"
+ size="md"
+ (click)="toggleContent()">
+ <span i18n>{{ isTruncated ? 'Read more' : 'Read less' }}</span>
+ </button>
+ }
+ </div>
+ </div>
+ </div>
+}
--- /dev/null
+@use '@carbon/colors';
+@use '@carbon/themes';
+@use './src/styles/vendor/variables' as vv;
+@use '@carbon/layout';
+
+.inline-tip-container {
+ position: relative;
+ background: linear-gradient(90deg, colors.$blue-90, colors.$purple-70);
+ color: vv.$white;
+ padding: layout.$spacing-05;
+
+ .inline-tip-body-content {
+ width: 80%;
+
+ .btn-toggle {
+ margin-top: layout.$spacing-05;
+ color: themes.$link-inverse-hover;
+
+ &:hover {
+ color: themes.$link-inverse-active;
+ }
+ }
+ }
+}
+
+.close-btn-position {
+ position: absolute;
+ top: 0;
+ right: 0;
+
+ .close-btn {
+ padding: 0;
+
+ svg {
+ fill: themes.$icon-on-color;
+ }
+ }
+}
+
+.inline-tip-bg-color:hover {
+ background-color: #7f3ae7;
+}
--- /dev/null
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { InlineMessageComponent } from './inline-message.component';
+import { ButtonModule, IconModule, LayoutModule } from 'carbon-components-angular';
+
+describe('InlineMessageComponent', () => {
+ let component: InlineMessageComponent;
+ let fixture: ComponentFixture<InlineMessageComponent>;
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [InlineMessageComponent],
+ imports: [LayoutModule, IconModule, ButtonModule]
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(InlineMessageComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should have default values for inputs', () => {
+ expect(component.collapsible).toBe(false);
+ expect(component.title).toBe('');
+ expect(component.onClose).toBeDefined();
+ });
+
+ it('should set collapsible input', () => {
+ component.collapsible = true;
+ expect(component.collapsible).toBe(true);
+ });
+
+ it('should set title input', () => {
+ component.title = 'Test Title';
+ expect(component.title).toBe('Test Title');
+ });
+
+ it('should call onClose and set isDismissed to true when Close is called', () => {
+ const onCloseSpy = jasmine.createSpy('onClose');
+ component.onClose = onCloseSpy;
+ component.isDismissed = false;
+ component.close();
+ expect(component.isDismissed).toBe(true);
+ expect(onCloseSpy).toHaveBeenCalled();
+ });
+
+ it('should toggle isTruncated when toggleContent is called', () => {
+ component.isTruncated = false;
+ component.toggleContent();
+ expect(component.isTruncated).toBe(true);
+ component.toggleContent();
+ expect(component.isTruncated).toBe(false);
+ });
+
+ it('should have icons property set to Icons enum', () => {
+ expect(component.icons).toBeDefined();
+ });
+});
--- /dev/null
+import { Component, Input } from '@angular/core';
+import { Icons } from '../../enum/icons.enum';
+
+@Component({
+ selector: 'cd-inline-message',
+ templateUrl: './inline-message.component.html',
+ styleUrl: './inline-message.component.scss'
+})
+export class InlineMessageComponent {
+ // collapsible when true will show read more/read less button
+ @Input()
+ collapsible = false;
+ // title to show in the message
+
+ @Input()
+ title = '';
+
+ // callback function to execute onclose
+ @Input()
+ onClose?: () => void = () => {};
+
+ isTruncated = false;
+ icons = Icons;
+ isDismissed = false;
+
+ close() {
+ this.isDismissed = true;
+ if (this.onClose) {
+ this.onClose();
+ }
+ }
+
+ toggleContent() {
+ this.isTruncated = !this.isTruncated;
+ }
+}
launch = 'launch',
parentChild = 'parent-child',
dataTable = 'data-table',
+ idea = 'idea',
/* Icons for special effect */
size16 = '16',
size20 = '20',
);
@use '@carbon/styles';
@use '@carbon/type';
+@use '@carbon/styles/scss/utilities/text-truncate' as textTruncate;
/******************************************
Custom theme
/******************************************
Datatable
******************************************/
-
:root {
@include type.type-classes();
}
.cds-mb-4 {
margin-bottom: layout.$spacing-02;
}
+
+.cds--text-truncate--end {
+ @include textTruncate.text-truncate-end;
+}