UNPKG

carbon-components-angular

Version:
523 lines (512 loc) 21.1 kB
import * as i0 from '@angular/core'; import { Component, HostBinding, Input, ViewChild, NgModule } from '@angular/core'; import * as i4 from 'carbon-components-angular/button'; import { BaseIconButton, ButtonModule } from 'carbon-components-angular/button'; import * as i1 from 'carbon-components-angular/i18n'; import { I18nModule } from 'carbon-components-angular/i18n'; import * as i2 from 'carbon-components-angular/utils'; import { UtilsModule } from 'carbon-components-angular/utils'; import * as i3 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i5 from 'carbon-components-angular/icon'; import { IconModule } from 'carbon-components-angular/icon'; var SnippetType; (function (SnippetType) { SnippetType["single"] = "single"; SnippetType["multi"] = "multi"; SnippetType["inline"] = "inline"; })(SnippetType || (SnippetType = {})); /** * Get started with importing the module: * * ```typescript * import { CodeSnippetModule } from 'carbon-components-angular'; * ``` * * ```html * <cds-code-snippet>Code</cds-code-snippet> * ``` * * [See demo](../../?path=/story/components-code-snippet--basic) */ class CodeSnippet extends BaseIconButton { /** * Creates an instance of CodeSnippet. */ constructor(i18n, eventService) { super(); this.i18n = i18n; this.eventService = eventService; this.rowHeightInPixel = 16; /** * It can be `"single"`, `"multi"` or `"inline"` */ this.display = SnippetType.single; this.translations = this.i18n.get().CODE_SNIPPET; /** * Set to `true` to hide copy button */ this.hideCopyButton = false; /** * Set to `true` to disable the code snippet */ this.disabled = false; /** * Specify the max number of rows to show when collapsed * Default is `15` */ this.maxCollapsedNumberOfRows = 15; /** * Specify the min number of rows to show when collapsed * Default is `3` */ this.minCollapsedNumberOfRows = 3; /** * Specify the max number of rows to show when expanded * Default is `0`, hence all content will be visible when expanded */ this.maxExpandedNumberOfRows = 0; /** * Specify the min number of rows to show when expanded * Default is `16`, hence height of expanded row will be 16 * rowHeightInPixel (16) = 256px */ this.minExpandedNumberOfRows = 16; /** * Set to `true` to wrap the text */ this.wrapText = false; /** * @deprecated since v5 - Use `cdsLayer` directive instead * Set to `"light"` to apply the light style */ this.theme = "dark"; /** * Text displayed in the tooltip when user clicks button to copy code. */ this.feedbackText = this.translations.COPIED; /** * Time in miliseconds to keep the feedback tooltip displayed. * Defaults to 2 seconds */ this.feedbackTimeout = 2000; this.expanded = false; this.skeleton = false; this.styles = {}; this.showFeedback = false; this.animating = false; this.hasExpandButton = null; this.isExpandable = false; this.hasRightOverflow = false; this.hasRight = false; this.hasLeft = false; this.dropShadow = false; } get snippetClass() { return this.display !== SnippetType.inline; } get snippetSingleClass() { return this.display === SnippetType.single; } get snippetMultiClass() { return this.display === SnippetType.multi; } get snippetDisabledClass() { return this.display !== "inline" && this.disabled; } get snippetInlineLightClass() { return this.theme === "light"; } handleScroll() { if (this.skeleton) { return; } let ref; switch (this.display) { case "multi": ref = this.codeContent.nativeElement; break; case "single": ref = this.codeContainer.nativeElement; break; default: return; } if (ref) { const { scrollWidth, clientWidth, scrollLeft } = ref; const horizontalOverflow = scrollWidth > clientWidth; this.hasLeft = horizontalOverflow && !!scrollLeft; this.hasRight = horizontalOverflow && scrollLeft + clientWidth !== scrollWidth; } } toggleSnippetExpansion() { this.expanded = !this.expanded; this.calculateContainerHeight(); } onCopyButtonClicked() { if (!this.disabled) { window.navigator.clipboard .writeText(this.code.nativeElement.innerText || this.code.nativeElement.textContent).then(() => { this.showFeedback = true; this.animating = true; setTimeout(() => { this.showFeedback = false; this.animating = false; }, this.feedbackTimeout); }); } } ngOnInit() { this.calculateContainerHeight(); } ngAfterViewInit() { this.canExpand(); this.handleScroll(); if (window) { this.eventService.on(window, "resize", () => { this.canExpand(); this.handleScroll(); }); } } calculateContainerHeight() { if (this.display === "multi" && !this.skeleton) { this.styles = {}; if (this.expanded) { if (this.maxExpandedNumberOfRows > 0) { this.styles["max-height"] = `${this.maxExpandedNumberOfRows * this.rowHeightInPixel}px`; } if (this.minExpandedNumberOfRows > 0) { this.styles["min-height"] = `${this.minExpandedNumberOfRows * this.rowHeightInPixel}px`; } } else { if (this.maxCollapsedNumberOfRows > 0) { this.styles["max-height"] = `${this.maxCollapsedNumberOfRows * this.rowHeightInPixel}px`; } if (this.minCollapsedNumberOfRows > 0) { this.styles["min-height"] = `${this.minCollapsedNumberOfRows * this.rowHeightInPixel}px`; } } } } canExpand() { if (this.display === "multi" && !this.skeleton) { const height = this.codeContent.nativeElement.getBoundingClientRect().height; if (this.maxCollapsedNumberOfRows > 0 && (this.maxExpandedNumberOfRows <= 0 || this.maxExpandedNumberOfRows > this.maxCollapsedNumberOfRows) && height > this.maxCollapsedNumberOfRows * this.rowHeightInPixel) { this.isExpandable = true; } else { this.isExpandable = false; } if (this.expanded && this.minExpandedNumberOfRows > 0 && height <= this.minExpandedNumberOfRows * this.rowHeightInPixel) { this.isExpandable = false; } } } } CodeSnippet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CodeSnippet, deps: [{ token: i1.I18n }, { token: i2.EventService }], target: i0.ɵɵFactoryTarget.Component }); CodeSnippet.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CodeSnippet, selector: "cds-code-snippet, ibm-code-snippet", inputs: { display: "display", translations: "translations", copyButtonDescription: "copyButtonDescription", hideCopyButton: "hideCopyButton", disabled: "disabled", maxCollapsedNumberOfRows: "maxCollapsedNumberOfRows", minCollapsedNumberOfRows: "minCollapsedNumberOfRows", maxExpandedNumberOfRows: "maxExpandedNumberOfRows", minExpandedNumberOfRows: "minExpandedNumberOfRows", wrapText: "wrapText", theme: "theme", feedbackText: "feedbackText", feedbackTimeout: "feedbackTimeout", expanded: "expanded", skeleton: "skeleton" }, host: { properties: { "class.cds--snippet": "this.snippetClass", "class.cds--snippet--single": "this.snippetSingleClass", "class.cds--snippet--multi": "this.snippetMultiClass", "class.cds--snippet--disabled": "this.snippetDisabledClass", "class.cds--snippet--light": "this.snippetInlineLightClass", "class.cds--snippet--wraptext": "this.wrapText", "class.cds--snippet--expand": "this.expanded", "class.cds--skeleton": "this.skeleton" } }, viewQueries: [{ propertyName: "code", first: true, predicate: ["code"], descendants: true }, { propertyName: "codeContent", first: true, predicate: ["codeContent"], descendants: true }, { propertyName: "codeContainer", first: true, predicate: ["codeContainer"], descendants: true }], usesInheritance: true, ngImport: i0, template: ` <ng-container *ngIf="display === 'inline'; else notInline"> <ng-container *ngIf="!hideCopyButton; else noBtnInline"> <ng-container *ngTemplateOutlet="buttonTemplate"></ng-container> </ng-container> <ng-template #noBtnInline> <span class="cds--snippet cds--snippet--inline cds--snippet--no-copy" [ngClass]="{ 'cds--snippet--light': theme === 'light' }"> <code #code> <ng-container *ngTemplateOutlet="codeTemplate"></ng-container> </code> </span> </ng-template> </ng-container> <ng-template #notInline> <div #codeContainer class="cds--snippet-container" [attr.aria-label]="translations.CODE_SNIPPET_TEXT" [attr.tabindex]="display === 'single' && !disabled ? '0' : null" [attr.role]="display==='single' ? 'textarea' : null" [ngStyle]="styles" (scroll)="(display === 'single' ? handleScroll() : null)"> <ng-container *ngIf="skeleton"> <span *ngIf="display === 'single'; else multiSkeleton"></span> <ng-template #multiSkeleton> <span></span> <span></span> <span></span> </ng-template> </ng-container> <pre #codeContent *ngIf="!skeleton" (scroll)="(display === 'multi' ? handleScroll() : null)"><code #code><ng-container *ngTemplateOutlet="codeTemplate"></ng-container></code></pre> </div> <div *ngIf="hasLeft" class="cds--snippet__overflow-indicator--left"></div> <div *ngIf="hasRight" class="cds--snippet__overflow-indicator--right"></div> <ng-container *ngIf="!hideCopyButton;"> <ng-container *ngTemplateOutlet="buttonTemplate"></ng-container> </ng-container> <button *ngIf="isExpandable" class="cds--btn cds--btn--ghost cds--btn--sm cds--snippet-btn--expand" (click)="toggleSnippetExpansion()" type="button"> <span class="cds--snippet-btn--text">{{expanded ? translations.SHOW_LESS : translations.SHOW_MORE}}</span> <svg cdsIcon="chevron--down" size="16" class="cds--icon-chevron--down" [attr.aria-label]="translations.SHOW_MORE_ICON"></svg> </button> </ng-template> <ng-template #buttonTemplate> <cds-icon-button *ngIf="!skeleton" [description]="showFeedback ? feedbackText : copyButtonDescription" [align]="align" [dropShadow]="dropShadow" [caret]="caret" [highContrast]="highContrast" [isOpen]="isOpen" [enterDelayMs]="enterDelayMs" [leaveDelayMs]="leaveDelayMs" type="button" kind="primary" size="md" (click)="onCopyButtonClicked($event)" [buttonNgClass]="{ 'cds--snippet--light': theme === 'light', 'cds--snippet--inline': display === 'inline', 'cds--btn--icon-only': display !== 'inline', 'cds--copy-btn': display !== 'inline', 'cds--copy-btn--animating': animating, 'cds--copy-btn--fade-in': showFeedback, 'cds--copy-btn--fade-out': !showFeedback && animating, 'cds--snippet cds--copy': true }" [buttonAttributes]="{ 'aria-label': translations.COPY_CODE, 'aria-live': 'polite', 'tabindex': '0' }"> <ng-container *ngIf="display === 'inline'"> <code #code> <ng-container *ngTemplateOutlet="codeTemplate"></ng-container> </code> </ng-container> <ng-container *ngIf="display !== 'inline'"> <svg cdsIcon="copy" size="16" class="cds--snippet__icon"></svg> </ng-container> </cds-icon-button> </ng-template> <ng-template #codeTemplate> <ng-content></ng-content> </ng-template> `, isInline: true, dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.IconButton, selector: "cds-icon-button, ibm-icon-button", inputs: ["buttonNgClass", "buttonAttributes", "buttonId", "kind", "size", "type", "isExpressive", "disabled", "description"], outputs: ["click", "focus", "blur", "tooltipClick"] }, { kind: "directive", type: i5.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CodeSnippet, decorators: [{ type: Component, args: [{ selector: "cds-code-snippet, ibm-code-snippet", template: ` <ng-container *ngIf="display === 'inline'; else notInline"> <ng-container *ngIf="!hideCopyButton; else noBtnInline"> <ng-container *ngTemplateOutlet="buttonTemplate"></ng-container> </ng-container> <ng-template #noBtnInline> <span class="cds--snippet cds--snippet--inline cds--snippet--no-copy" [ngClass]="{ 'cds--snippet--light': theme === 'light' }"> <code #code> <ng-container *ngTemplateOutlet="codeTemplate"></ng-container> </code> </span> </ng-template> </ng-container> <ng-template #notInline> <div #codeContainer class="cds--snippet-container" [attr.aria-label]="translations.CODE_SNIPPET_TEXT" [attr.tabindex]="display === 'single' && !disabled ? '0' : null" [attr.role]="display==='single' ? 'textarea' : null" [ngStyle]="styles" (scroll)="(display === 'single' ? handleScroll() : null)"> <ng-container *ngIf="skeleton"> <span *ngIf="display === 'single'; else multiSkeleton"></span> <ng-template #multiSkeleton> <span></span> <span></span> <span></span> </ng-template> </ng-container> <pre #codeContent *ngIf="!skeleton" (scroll)="(display === 'multi' ? handleScroll() : null)"><code #code><ng-container *ngTemplateOutlet="codeTemplate"></ng-container></code></pre> </div> <div *ngIf="hasLeft" class="cds--snippet__overflow-indicator--left"></div> <div *ngIf="hasRight" class="cds--snippet__overflow-indicator--right"></div> <ng-container *ngIf="!hideCopyButton;"> <ng-container *ngTemplateOutlet="buttonTemplate"></ng-container> </ng-container> <button *ngIf="isExpandable" class="cds--btn cds--btn--ghost cds--btn--sm cds--snippet-btn--expand" (click)="toggleSnippetExpansion()" type="button"> <span class="cds--snippet-btn--text">{{expanded ? translations.SHOW_LESS : translations.SHOW_MORE}}</span> <svg cdsIcon="chevron--down" size="16" class="cds--icon-chevron--down" [attr.aria-label]="translations.SHOW_MORE_ICON"></svg> </button> </ng-template> <ng-template #buttonTemplate> <cds-icon-button *ngIf="!skeleton" [description]="showFeedback ? feedbackText : copyButtonDescription" [align]="align" [dropShadow]="dropShadow" [caret]="caret" [highContrast]="highContrast" [isOpen]="isOpen" [enterDelayMs]="enterDelayMs" [leaveDelayMs]="leaveDelayMs" type="button" kind="primary" size="md" (click)="onCopyButtonClicked($event)" [buttonNgClass]="{ 'cds--snippet--light': theme === 'light', 'cds--snippet--inline': display === 'inline', 'cds--btn--icon-only': display !== 'inline', 'cds--copy-btn': display !== 'inline', 'cds--copy-btn--animating': animating, 'cds--copy-btn--fade-in': showFeedback, 'cds--copy-btn--fade-out': !showFeedback && animating, 'cds--snippet cds--copy': true }" [buttonAttributes]="{ 'aria-label': translations.COPY_CODE, 'aria-live': 'polite', 'tabindex': '0' }"> <ng-container *ngIf="display === 'inline'"> <code #code> <ng-container *ngTemplateOutlet="codeTemplate"></ng-container> </code> </ng-container> <ng-container *ngIf="display !== 'inline'"> <svg cdsIcon="copy" size="16" class="cds--snippet__icon"></svg> </ng-container> </cds-icon-button> </ng-template> <ng-template #codeTemplate> <ng-content></ng-content> </ng-template> ` }] }], ctorParameters: function () { return [{ type: i1.I18n }, { type: i2.EventService }]; }, propDecorators: { snippetClass: [{ type: HostBinding, args: ["class.cds--snippet"] }], snippetSingleClass: [{ type: HostBinding, args: ["class.cds--snippet--single"] }], snippetMultiClass: [{ type: HostBinding, args: ["class.cds--snippet--multi"] }], snippetDisabledClass: [{ type: HostBinding, args: ["class.cds--snippet--disabled"] }], snippetInlineLightClass: [{ type: HostBinding, args: ["class.cds--snippet--light"] }], display: [{ type: Input }], translations: [{ type: Input }], copyButtonDescription: [{ type: Input }], hideCopyButton: [{ type: Input }], disabled: [{ type: Input }], maxCollapsedNumberOfRows: [{ type: Input }], minCollapsedNumberOfRows: [{ type: Input }], maxExpandedNumberOfRows: [{ type: Input }], minExpandedNumberOfRows: [{ type: Input }], wrapText: [{ type: HostBinding, args: ["class.cds--snippet--wraptext"] }, { type: Input }], theme: [{ type: Input }], feedbackText: [{ type: Input }], feedbackTimeout: [{ type: Input }], expanded: [{ type: HostBinding, args: ["class.cds--snippet--expand"] }, { type: Input }], skeleton: [{ type: HostBinding, args: ["class.cds--skeleton"] }, { type: Input }], code: [{ type: ViewChild, args: ["code"] }], codeContent: [{ type: ViewChild, args: ["codeContent"] }], codeContainer: [{ type: ViewChild, args: ["codeContainer"] }] } }); // modules class CodeSnippetModule { } CodeSnippetModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CodeSnippetModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); CodeSnippetModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: CodeSnippetModule, declarations: [CodeSnippet], imports: [CommonModule, ButtonModule, I18nModule, UtilsModule, IconModule], exports: [CodeSnippet] }); CodeSnippetModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CodeSnippetModule, imports: [CommonModule, ButtonModule, I18nModule, UtilsModule, IconModule] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CodeSnippetModule, decorators: [{ type: NgModule, args: [{ declarations: [ CodeSnippet ], exports: [ CodeSnippet ], imports: [ CommonModule, ButtonModule, I18nModule, UtilsModule, IconModule ] }] }] }); /** * Generated bundle index. Do not edit. */ export { CodeSnippet, CodeSnippetModule, SnippetType }; //# sourceMappingURL=carbon-components-angular-code-snippet.mjs.map