diff --git a/samples/sample-actions-bar-plugin/src/sample-actions-bar-plugin/component.tsx b/samples/sample-actions-bar-plugin/src/sample-actions-bar-plugin/component.tsx index 2a81b7cd..d4c1019c 100644 --- a/samples/sample-actions-bar-plugin/src/sample-actions-bar-plugin/component.tsx +++ b/samples/sample-actions-bar-plugin/src/sample-actions-bar-plugin/component.tsx @@ -2,8 +2,8 @@ import * as React from 'react'; import { useEffect } from 'react'; import { - ActionsBarButton, ActionsBarInterface, ActionsBarPosition, ActionsBarSeparator, - BbbPluginSdk, GraphqlResponseWrapper, + ActionsBarButton, ActionsBarInterface, ActionsBarPosition, ActionsBarSelector, + ActionsBarSeparator, ActionsBarToggleGroup, BbbPluginSdk, GraphqlResponseWrapper, PluginApi, UsersBasicInfoResponseFromGraphqlWrapper, pluginLogger, } from 'bigbluebutton-html-plugin-sdk'; @@ -14,6 +14,14 @@ function SampleActionsBarPlugin({ }: SampleActionsBarPluginProps): React.ReactNode { BbbPluginSdk.initialize(uuid); const pluginApi: PluginApi = BbbPluginSdk.getPluginApi(uuid); + const options = [ + { value: 1, label: 'one' }, + { value: 2, label: 'two' }, + { value: 3, label: 'three' }, + { value: 4, label: 'four' }, + { value: 5, label: 'five' }, + { value: 6, label: 'six' }, + ]; useEffect(() => { const buttonToUserListItem: @@ -21,16 +29,47 @@ function SampleActionsBarPlugin({ icon: 'user', tooltip: 'This will log on the console.', onClick: () => { - pluginLogger.info('The action bar button from plugin was clicked'); + pluginLogger.info('The actions bar button from plugin was clicked'); }, position: ActionsBarPosition.RIGHT, }); - const dropdownToUserListItem: + const separatorToUserListItem: ActionsBarInterface = new ActionsBarSeparator({ position: ActionsBarPosition.RIGHT, }); + const selectorItem: ActionsBarInterface = new ActionsBarSelector({ + title: 'Selector', + options, + defaultOption: options[4], + onChange: (value, event) => { + console.log({ value, event }); + pluginLogger.info('The actions bar selector has changed', { value, event }); + }, + position: ActionsBarPosition.RIGHT, + width: 150, // To define a specific width, uncomment this line + }); + const separatorIconItem: ActionsBarInterface = new ActionsBarSeparator({ + position: ActionsBarPosition.RIGHT, + icon: 'whiteboard', + }); + const toggleGroupItem: ActionsBarInterface = new ActionsBarToggleGroup({ + title: 'Toggle', + options: options.slice(0, 2), // Toggle groups can have more than 2 options + defaultOption: options[2], + onChange: (value, event) => { + pluginLogger.info('The actions bar toggle group has changed', { value, event: event.nativeEvent }); + }, + position: ActionsBarPosition.RIGHT, + // exclusive: false, // To allow for checking more than one option, uncomment this line + }); - pluginApi.setActionsBarItems([dropdownToUserListItem, buttonToUserListItem]); + pluginApi.setActionsBarItems([ + separatorToUserListItem, + buttonToUserListItem, + selectorItem, + separatorIconItem, + toggleGroupItem, + ]); }, []); const users: GraphqlResponseWrapper = pluginApi diff --git a/src/extensible-areas/actions-bar-item/component.ts b/src/extensible-areas/actions-bar-item/component.ts index 26d3e352..62544aa8 100644 --- a/src/extensible-areas/actions-bar-item/component.ts +++ b/src/extensible-areas/actions-bar-item/component.ts @@ -1,21 +1,45 @@ +import { ChangeEvent, MouseEvent } from 'react'; import { ActionsBarPosition, ActionsBarItemType } from './enums'; import { - ActionsBarInterface, ActionsBarButtonProps, ActionsBarSeparatorProps, + ActionsBarInterface, + ActionsBarItemProps, + ActionsBarButtonProps, + ActionsBarSeparatorProps, + ActionsBarSelectorProps, + SelectOption, + ToggleGroupOption, + ActionsBarToggleGroupProps, } from './types'; // ActionsBar Extensible Area -export class ActionsBarButton implements ActionsBarInterface { +class ActionsBarItem implements ActionsBarInterface { id: string = ''; type: ActionsBarItemType; + position: ActionsBarPosition; + + constructor({ + id, type, position = ActionsBarPosition.RIGHT, + }: ActionsBarItemProps) { + if (id) { + this.id = id; + } + this.type = type; + this.position = position; + } + + setItemId(id: string):void { + this.id = `ActionsBar${this.type}_${id}`; + } +} + +export class ActionsBarButton extends ActionsBarItem { icon: string; tooltip: string; - position: ActionsBarPosition; - onClick: () => void; /** @@ -32,44 +56,120 @@ export class ActionsBarButton implements ActionsBarInterface { constructor({ id, icon = '', tooltip = '', onClick = () => {}, position = ActionsBarPosition.RIGHT, }: ActionsBarButtonProps) { - if (id) { - this.id = id; - } + super({ id, type: ActionsBarItemType.BUTTON, position }); this.icon = icon; this.tooltip = tooltip; this.onClick = onClick; - this.position = position; - this.type = ActionsBarItemType.BUTTON; } +} - setItemId: (id: string) => void = (id: string) => { - this.id = `ActionsBarButton_${id}`; - }; +export class ActionsBarSeparator extends ActionsBarItem { + icon: string; + + /** + * Returns object to be used in the setter for action bar. In this case, + * a separator. + * + * @param position - position that this button will be displayed, see {@link ActionsBarPosition} + * @param icon - Icon to be displayed as the separator. If not provided, the default separator + * (a vertical bar) will be displayed. + * + * @returns Object that will be interpreted by the core of Bigbluebutton (HTML5) + */ + constructor({ + position = ActionsBarPosition.RIGHT, + icon = '', + }: ActionsBarSeparatorProps) { + super({ type: ActionsBarItemType.SEPARATOR, position }); + this.icon = icon; + } } -export class ActionsBarSeparator implements ActionsBarInterface { - position: ActionsBarPosition; +export class ActionsBarSelector extends ActionsBarItem { + title: string; - id: string = ''; + options: SelectOption[]; - type: ActionsBarItemType; + defaultOption: SelectOption; + + onChange: (value: string | number, event: ChangeEvent) => void; + + width: number = 145; /** * Returns object to be used in the setter for action bar. In this case, - * a separator. + * a selector. * + * @param title - title to be used in the selector for the actions bar + * @param options - an array of options to be available in the selector + * @param defaultOption - the option to be initially selected, if not present, the first option is + * selected + * @param onChange - function to be called when selected value changes * @param position - position that this button will be displayed, see {@link ActionsBarPosition} + * @param width - desired width for the selector in px, default is 140 * * @returns Object that will be interpreted by the core of Bigbluebutton (HTML5) */ + constructor({ + id, + title = '', + options = [], + defaultOption = options[0], + onChange = () => {}, position = ActionsBarPosition.RIGHT, - }: ActionsBarSeparatorProps) { - this.position = position; - this.type = ActionsBarItemType.SEPARATOR; + width = 140, + }: ActionsBarSelectorProps) { + super({ id, type: ActionsBarItemType.SELECTOR, position }); + this.title = title; + this.options = options; + this.defaultOption = defaultOption; + this.onChange = onChange; + this.width = width; } +} + +export class ActionsBarToggleGroup extends ActionsBarItem { + title: string; - setItemId: (id: string) => void = (id: string) => { - this.id = `ActionsBarSeparator_${id}`; - }; + exclusive: boolean; + + options: ToggleGroupOption[]; + + defaultOption: ToggleGroupOption; + + onChange: (values: string | number | string[] | number[], event: MouseEvent) => void; + + /** + * Returns object to be used in the setter for action bar. In this case, + * a toggle group. + * + * @param title - title to be used in the selector for the actions bar + * @param exclusive - whether the toggle group should be exclusive or not - allow checking + * multiple options + * @param options - an array of options to be available in the toggle group + * @param defaultOption - the option to be initially checked, if not present, the first option is + * checked + * @param onChange - function to be called when checked value changes + * @param position - position that this button will be displayed, see {@link ActionsBarPosition} + * + * @returns Object that will be interpreted by the core of Bigbluebutton (HTML5) + */ + + constructor({ + id, + title = '', + exclusive = true, + options = [], + defaultOption = options[0], + onChange = () => {}, + position = ActionsBarPosition.RIGHT, + }: ActionsBarToggleGroupProps) { + super({ id, type: ActionsBarItemType.TOGGLE_GROUP, position }); + this.title = title; + this.exclusive = exclusive; + this.options = options; + this.defaultOption = defaultOption; + this.onChange = onChange; + } } diff --git a/src/extensible-areas/actions-bar-item/enums.ts b/src/extensible-areas/actions-bar-item/enums.ts index 9de5c63f..30389291 100644 --- a/src/extensible-areas/actions-bar-item/enums.ts +++ b/src/extensible-areas/actions-bar-item/enums.ts @@ -2,6 +2,8 @@ export enum ActionsBarItemType { BUTTON = 'ACTIONS_BAR_BUTTON', SEPARATOR = 'ACTIONS_BAR_SEPARATOR', + SELECTOR = 'ACTIONS_BAR_SELECTOR', + TOGGLE_GROUP = 'ACTIONS_BAR_TOGGLE_GROUP', } /** diff --git a/src/extensible-areas/actions-bar-item/index.ts b/src/extensible-areas/actions-bar-item/index.ts index 46379a96..0b8dcd89 100644 --- a/src/extensible-areas/actions-bar-item/index.ts +++ b/src/extensible-areas/actions-bar-item/index.ts @@ -1,10 +1,13 @@ export { ActionsBarButton, ActionsBarSeparator, + ActionsBarSelector, + ActionsBarToggleGroup, } from './component'; export { ActionsBarInterface, } from './types'; export { + ActionsBarItemType, ActionsBarPosition, } from './enums'; diff --git a/src/extensible-areas/actions-bar-item/types.ts b/src/extensible-areas/actions-bar-item/types.ts index e27624f6..19870f1e 100644 --- a/src/extensible-areas/actions-bar-item/types.ts +++ b/src/extensible-areas/actions-bar-item/types.ts @@ -1,5 +1,6 @@ +import { ChangeEvent, MouseEvent } from 'react'; import { PluginProvidedUiItemDescriptor } from '../base'; -import { ActionsBarPosition } from './enums'; +import { ActionsBarItemType, ActionsBarPosition } from './enums'; /** * Interface for the generic Actions bar item. (`position` is mandatory) @@ -8,6 +9,12 @@ export interface ActionsBarInterface extends PluginProvidedUiItemDescriptor{ position: ActionsBarPosition; } +export interface ActionsBarItemProps { + id?: string; + position: ActionsBarPosition; + type: ActionsBarItemType; +} + export interface ActionsBarButtonProps { id?: string; icon: string; @@ -18,4 +25,33 @@ export interface ActionsBarButtonProps { export interface ActionsBarSeparatorProps { position: ActionsBarPosition; + icon?: string; +} + +export interface SelectOption { + value: string | number; + label: string; +} + +export interface ToggleGroupOption extends SelectOption { +} + +export interface ActionsBarSelectorProps { + id?: string; + title: string; + options: SelectOption[]; + defaultOption?: SelectOption; + onChange: (value: string | number, event: ChangeEvent) => void; + position: ActionsBarPosition; + width?: number; +} + +export interface ActionsBarToggleGroupProps { + id?: string; + title: string; + options: ToggleGroupOption[]; + defaultOption?: ToggleGroupOption; + exclusive?: boolean; + onChange: (values: string | number | string[] | number[], event: MouseEvent) => void; + position: ActionsBarPosition; }