Skip to content

Platform: Grouped Button Component V1.0 Technical Design

sKudum edited this page Oct 1, 2019 · 63 revisions

Button Component

Summary

Also called Segmented buttons:

This is a composite component consisting of two or more normal buttons logically grouped. For each individual button, the functionality and design are as defined for normal button component.

Design

buttonGroupExample.component.html/signature

 <fdp-buttons-group 
         [buttons]="buttonList" 
         [size]='xs'
         [type]='type'
         [options]='option'
         [compact]='true|false'>
<fdp-buttons-group>

buttonGroupExample.component.ts

export class ButtonGoupeExampleComponent implements ngInit{

//*****instance of the groupBtn it holds common values to all the buttons.***/

 @Input() buttonList<fd-button>: GroupBtnItems[]=[];
          
         ngOninit(){
         this.buttonList.push(new GroupBtnItem('button1', 'btn1'...));
         this.buttonList.push(new GroupBtnItem('button2', 'btn2',...));}
}
}

Property Bindings in ==> button component V1.0


Along with the existing options in button component below options will be added in it

fdButtonGroupedClass: boolean = false;

if it true then button will act as grouped button

    @HostBinding('class.fd-button--grouped')
    fdButtonGroupedClass: boolean = false;
#### `state: is-selected | is-disabled | is-default`
In state user can set the state of the button by default it will be in dafult state

---

### Property Bindings in ==> button Group component V1.0
***
#### `  @Input() type:string;`
#### `  @Input() options: string;`
#### ` @Input() size: small | xtra-small | large`
Button size can be set based on the form where it is placed as small, xtra small and large.

Implemented from GroupButton interface used for all the button components.

### Event Bindings==> button Group component V1.0
***
```html 
 /**@Hiden**/
onChangeValues(data: any) {
    this.data = data;
    const clickedElement = data.target || data.srcElement;
    const isCertainButtonAlreadyActive = clickedElement.parentElement.querySelector(
      '.is-selected'
    );
    if (isCertainButtonAlreadyActive) {
      isCertainButtonAlreadyActive.classList.remove('is-selected');
      isCertainButtonAlreadyActive.classList.add('is-default');
      clickedElement.classList.remove('is-default');
      clickedElement.classList.add('is-selected');
    }
  }

This will fix the grouped button bugs found in fundamental-ngx/core.

  1. On select of another button previous button remains selected.
  2. On click, on the screen anywhere the selected button will become unselected.

button-goup-component.ts

**ButtonGoupComponent.ts**
import {GroupBtnItem} from ./GroupButtonItems;
@Component({
    selector: 'fdp-group-button',
    templateUrl: './buttonGroup.component.html',
    styleUrls: ['./buttonGroup.component.scss']
})
export class ButtonGoupComponent implements ngInit,GroupBtnItem{
//instance of the groupBtn it holds common values to all the buttons.
 @Input() buttons: ButtonComponent[]=[];
 @Input() size: string;
 @Input() type:string;
 /**@Hiden**/
onChangeValues(data: any) {
    this.data = data;
    const clickedElement = data.target || data.srcElement;
    const isCertainButtonAlreadyActive = clickedElement.parentElement.querySelector(
      '.is-selected'
    );
    if (isCertainButtonAlreadyActive) {
      isCertainButtonAlreadyActive.classList.remove('is-selected');
      isCertainButtonAlreadyActive.classList.add('is-default');
      clickedElement.classList.remove('is-default');
      clickedElement.classList.add('is-selected');
    }
  }

         ngOninit(){}
}
}

button-group.component.html

<div class="fd-button--grouped" *ngFor="let grpButton of buttons">
          <fdp-button [fdButtonGroupedClass]='true' [id]='grpButton.id' [size]='parent.size' [type]='parent.type'.......>
         {{grpButton.label}}
</fdp-button>   
</div>


---

### Two-Way Bindings

N/A

---

### Content Projection

N/A

---

### Interfaces

---

### Related Modules

The following components and/or directives from `@fundamental-ngx/core` will be used:

* [ButtonGroupModule, ButtonModule](https://sap.github.io/fundamental-ngx/button)

### Additional Notes

---

## Questions
@Frank,@Kevin,

* Can I use the existing fdp-button component to append features of the fd-button-group directive?

@Manju,

 In FRD it is mentioned max 3 buttons can be grouped. Does this mean I need to add any restrictions for the user not to add more than 3 and less than 2? As per my understanding user should have the freedom on number of buttons they want to add in the group. Please do let me know in case my understanding is wrong on this.


@Kit,kenny,

On hover and on select CSS colors for segmented/grouped button will be same as a normal button? if yes, then how I can calculate the values of colors if the grouped buttons are used in the different background color.
For example: on behalf of the bar background color is #323C4C in this case How I have to decide?
    * We are using fundamentals we should redirect this question to them. 

@Frank

* Yes we should reuse existing buttons yes. Just like I already comment let;s not use  btnxxx => `btnSize` we are working with buttons no need to say bTN in the binding, just size. The same applies for FD as fundamentals. 

* When dealing with button group we need to be able to specify if single / multi. 
   * When I press 1 butotn others will pop ups. so only 1 button at the time is pushed
   * or multi mode where I can pre 1 or all. 
* Button should have a name / ID . I know we said that we dont need `id` but we will need it here the 'id'
* Does it make sense to let application developer specify all these bindings every time? Wwhen we have button group in 99% we have size identical, so does other bindings. 
    * let's have some bindings on hte button group as well, and button inside will inherit/ 
       * I can specify e.g. size only once
* I woudl like to see also programatic way of assembing Button Groups, Introduce a interface to represent button

e.g. for the first case I mentioned it could be :
```html

<fdp-buttons-group size="XL" click="clickEvent($event)" options="ddd">

<fdp-button
                      [fdButtonGroupedClass]=true
                      [btnState]="state" 
                      [glyph]="glyph"
                      [disabled]="disabled" 
                      [type]="type">Button Content
       </fdp-button>
  • Group buttons will have have some uniformity, It cant really happen that for 1 button we will have text for other not. This is why we should be able to have some bindings that could be applied here.

The programatic way could be:

<fdp-buttons-group [buttons]="buttonList"> 
<fdp-buttons-group>

export interface GroupBtnItem {
  size: number,
  state: BtnState,
  ... 
}
* but this is more nice to have
* Can button appear vertical ? 

      ==> Split button requirements speaks about it. As per my understanding, it handles it. 

        @Manju can confirm on the same
**button.component.ts**
import { Component, Input, ElementRef, Output, EventEmitter, OnInit } from '@angular/core';

export type ButtonType = 'standard' | 'positive' | 'medium' | 'negative' | 'toolbar' | 'main';
export type ButtonOptions = 'light' | 'emphasized' | '';

export interface GroupBtnItem {
                   size:string;
                   state:string;
                   options:string;
                   compress:boolean;
                   type:type;
}

@Component({
   selector: 'fdp-button',
   templateUrl: './button.component.html',
   styleUrls: ['./button.component.scss']
})
export class ButtonComponent {
   private _elementRef: ElementRef;
   /** instance of group button to access the values based on the object ref***/
    @Input 
    grpbtn:GroupBtnItem;

   /** Whether to compress the button. */
   @Input() compress: boolean;

   /** The icon to include in the button */
   @Input() glyph: string;

   /** Whether the button is disabled. */
   @Input()
   disabled: boolean;

   /** The type of the button. Types include 'standard', 'positive', 'medium', and 'negative'.
    * Leave empty for default (Action button).'*/
   @Input() type: ButtonType;

   /** Button options.  Options include 'emphasized' and 'light'. Leave empty for default.' */
   @Input() options: ButtonOptions | ButtonOptions[];

   /** Event sent when button is clicked */
   @Output()
   buttonClicked = new EventEmitter();

   /**
    *  Handles button click
    */
   public onBtnClick($event: any) {
       this.buttonClicked.emit();
   }

**ButtonGoupComponent.ts**
import {GroupBtnItem} from ./GroupButtonItems;
@Component({
   selector: 'fdp-group-button',
   templateUrl: './buttonGroup.component.html',
   styleUrls: ['./buttonGroup.component.scss']
})
export class ButtonGoupComponent implements ngInit,GroupBtnItem{
//instance of the groupBtn it holds common values to all the buttons.
@Input() buttons: ButtonComponent[]=[];
@Input() size: string;
@Input() type:string;

        ngOninit(){}
}
}


**button-group.component.html**

<div class="fd-button--grouped" *ngFor="let grpButton of buttons">
         <fdp-button [id]='grpButton.id' [size]='grpButton.size'>
        {{grpButton.label}}
</fdp-button>   
</div>
**buttonGroupExample.component.html**
<fdp-buttons-group [buttons]="buttonList" [size]='xs' [type]='option'><fdp-buttons-group>
***buttonGroupExample.component.ts**
export class ButtonGoupeExampleComponent implements ngInit{
//instance of the groupBtn it holds common values to all the buttons.
@Input() buttonList: GroupBtnItems[]=[];
         
        ngOninit(){
        this.buttonList.push(new GroupBtnItem('button1', 'btn1'...));
        this.buttonList.push(new GroupBtnItem('button2', 'btn2',...));}
}
}
        
Clone this wiki locally