Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Button): Add support for two icon buttons #1643

Merged
merged 7 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 39 additions & 8 deletions projects/novo-elements/src/elements/button/Button.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
// NG2
import { ChangeDetectionStrategy, Component, ElementRef, HostBinding, HostListener, Input, OnChanges, SimpleChanges } from '@angular/core';
import {
ChangeDetectionStrategy,
Component, computed,
ElementRef,
HostBinding,
HostListener, input,
Input,
InputSignal,
OnChanges, signal, Signal,
SimpleChanges, WritableSignal,
} from '@angular/core';
import { BooleanInput, Helpers, Key } from 'novo-elements/utils';

@Component({
Expand Down Expand Up @@ -27,11 +37,11 @@ import { BooleanInput, Helpers, Key } from 'novo-elements/utils';

template: `
<!--Left Icon-->
<i *ngIf="icon && side === 'left' && !loading" [ngClass]="icon" class="novo-button-icon novo-button-icon-left"></i>
<i *ngIf="((icon && side === 'left') || (secondIcon && secondSide() === 'left')) && !loading" [ngClass]="leftSideIconClass()" class="novo-button-icon novo-button-icon-left"></i>
<!--Transcluded Content-->
<span #textContent class="button-contents"><ng-content></ng-content></span>
<!--Right Icon-->
<i *ngIf="icon && side === 'right' && !loading" [ngClass]="icon" class="novo-button-icon novo-button-icon-right"></i>
<i *ngIf="((icon && side === 'right') || (secondIcon && secondSide() === 'right')) && !loading" [ngClass]="rightSideIconClass()" class="novo-button-icon novo-button-icon-right"></i>
<!--Loading-->
<i *ngIf="loading" class="loading novo-button-loading">
<svg
Expand Down Expand Up @@ -70,9 +80,12 @@ export class NovoButtonElement implements OnChanges {
@Input() color: string;
/**
* The side of the button to display the icon.
* @deprecated
*/
@Input() side: string = 'right';
/**
* If a second icon is specified it will default to the opposite side as the primary icon.
*/
secondSide: Signal<string> = computed(() => this.side === 'right' ? 'left' : 'right')
/**
* Sets the size of the button. One of: sm, lg
*/
Expand All @@ -87,18 +100,34 @@ export class NovoButtonElement implements OnChanges {
@Input() loading: boolean;
/**
* Optionally display `bullhorn-icon` with the button along with the text.
* @deprecated
*/
@Input()
set icon(icon: string) {
if (icon) {
this._icon = `bhi-${icon}`;
this._icon.set(`bhi-${icon}`);
}
}
get icon(): string {
return this._icon;
return this._icon();
}

/**
* A second icon can be specified, and it will take the opposite side of the primary icon.
*/
@Input()
set secondIcon(icon: string) {
if (icon) {
this._secondIcon.set(`bhi-${icon}`);
}
}
get secondIcon(): string {
return this._secondIcon();
}

leftSideIconClass: Signal<string> = computed(() => this.side === 'left' ? this._icon() : this._secondIcon());

rightSideIconClass: Signal<string> = computed(() => this.side === 'right' ? this._icon() : this._secondIcon());

/**
* Make the button non-interactive.
*/
Expand All @@ -110,7 +139,9 @@ export class NovoButtonElement implements OnChanges {
@HostBinding('attr.disabled')
disabledAttr: undefined | '' = undefined;

private _icon: string;
private _icon: WritableSignal<string> = signal(undefined);

private _secondIcon: WritableSignal<string> = signal(undefined);

constructor(public element: ElementRef) {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,9 @@ Button parameters can be dynamically set and change at runtime. The styles shoul
Buttons can display a loading state when given the "loading" parameter. When loading is true the button will be disabled and get a loading spinner.

<code-example example="button-loading"></code-example>

## Two Icons

A second icon can be specified, and it will take the opposite side of the primary icon.

<code-example example="button-two-icon"></code-example>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** No CSS for this example */

button {
margin: 1rem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<button theme="primary" icon="edit" secondIcon="arrow-right">Two Icons</button>
<button theme="primary" icon="bolt" secondIcon="configure-o" side="right">Two Icons</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Component } from '@angular/core';

/**
* @title Icon buttons
*/
@Component({
selector: 'button-two-icon-example',
templateUrl: 'button-two-icon-example.html',
styleUrls: ['button-two-icon-example.css'],
})
export class ButtonTwoIconExample {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './button-two-icon-example';
1 change: 1 addition & 0 deletions projects/novo-examples/src/components/buttons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './button-overview';
export * from './button-primary';
export * from './button-secondary';
export * from './button-standard';
export * from './button-two-icon';
Loading