microsoft / microsoft/BotFramework-WebChat

Investigate Web Chat Editor, playground, and Web Chat Designer

Open
#3,515 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

backlog front-burner needs-scheduling needs-team-attention team-agility
Dominant language
HTML
Stars
1.8k
Forks
1.6k
Avg merge
22h 58m
Merged PRs (30d)
2

Description

  • Compare the three projects and plan to bring alignment & reduce overlapping work
  • Expand scope of playground with action items for the following:
    • a demo app/playground
    • Composer extension
    • future hosting surfaces yet to be defined

Current resources:

import React, { useState } from 'react';
import AdaptiveForm  from '@bfc/adaptive-form';
import ReactWebChat from 'botframework-webchat';
import { JSONSchema7 } from '@bfc/extension-client';

const schema: JSONSchema7 = {
	"title": "Web Chat Designer",
	"description": "Web Chat Designer",
	"type": "object",
	"properties": {
		"accent": {
			"$role": "color",
			"type": "string"
		},
		"backgroundColor": {
				"$role": "color",
				"type": "string"
		},
		"cardEmphasisBackgroundColor": {
			"$role": "color",
			"type": "string"
		},
		"paddingRegular": {
			"oneOf":[
				{
						"type": "string"
				},
				{
					"type": "number"
				}
			]
		},
		"paddingWide": {
			"oneOf":[
				{
						"type": "string"
				},
				{
					"type": "number"
				}
			]
		},
		"subtle": {
			"$role": "color",
			"type": "string"
		},

		"messageActivityWordBreak": {
			"type": "string",
			"enum": [
				"break-word",
				"normal",
				"break-all",
				"break-word", 
				"keep-all"
			]
		},
		"fontSizeSmall": {
			"type": "string"
		},
		"monospaceFont": {
			"type": "string"
		},
		"primaryFont": {
			"type": "string"
		},
		"avatarBorderRadius": {
			"type": "string"
		},
		"avatarSize": {
			"oneOf":[
				{
						"type": "string"
				},
				{
					"type": "number"
				}
			]
		},
		"botAvatarBackgroundColor": {
			"$role": "color",
			"description": "defaults to accent color",
			"type": "string"
		},
		"botAvatarImage": {
			"description": "Data URI, blob, or Image URL",
			"type": "string"
		},
		"botAvatarInitials": {
			"description": "Empty strings means it has avatar but not initials inside.",
			"type": "string"
		},
		"userAvatarBackgroundColor": {
			"$role": "color",
			"description": "defaults to accent color",
			"type": "string"
		},
		"userAvatarImage": {
			"description": "Or a string of URL. Can be a data URI or blob.",
			"type": "string"
		},
		"userAvatarInitials": {
			"description": "Or a string. Empty strings means it has avatar but not initials inside.",
			"type": "string"
		},
		"showAvatarInGroup": {
			"oneOf": [
				{
					"type": "boolean"
				},
				{
					"type": "string",
					"enum": [
						"status",
						"sender"
					]
				}
			]
		},
		"bubbleBackground": {
			"$role": "color",
			"type": "string"
		},
		"bubbleBorderColor": {
			"$role": "color",
			"type": "string"
		},
		"bubbleBorderRadius": {
			"type": "number"
		},
		"bubbleBorderStyle": {
			"type": "string",
			"enum": [
				"dotted",
				"dashed",
				"solid",
				"double",
				"groove",
				"ridge",
				"inset",
				"outset",
				"none",
				"hidden",
				"mix"
			]
		},
		"bubbleBorderWidth": {
			"type": "number"
		},
		"bubbleFromUserBackground": {
			"$role": "color",
			"type": "string"
		},
		"bubbleFromUserBorderColor": {
			"$role": "color",
			"type": "string"
		},
		"bubbleFromUserBorderRadius": {
			"type": "number"
		},
		"bubbleFromUserBorderStyle": {
			"type": "string",
			"enum": [
				"dotted",
				"dashed",
				"solid",
				"double",
				"groove",
				"ridge",
				"inset",
				"outset",
				"none",
				"hidden",
				"mix"
			]
		},
		"bubbleFromUserBorderWidth": {
			"type": "number"
		},
		"bubbleFromUserNubOffset": {
			"oneOf": [
				{
					"type": "string",
					"const": "bottom"
				},
				{
					"type": "number"
				}
			]
		},
		"bubbleFromUserNubSize": {
			"type": "number"
		},
		"bubbleFromUserTextColor": {
			"$role": "color",
			"type": "string"
		},
		"bubbleImageHeight": {
			"type": "number"
		},
		"bubbleMaxWidth": {
			"type": "number"
		},
		"bubbleMinHeight": {
			"type": "number"
		},
		"bubbleMinWidth": {
			"type": "number"
		},
		"bubbleNubOffset": {
			"type": "number"
		},
		"bubbleNubSize": {
			"type": "number"
		},
		"bubbleTextColor": {
			"$role": "color",
			"type": "string"
		},
		"markdownRespectCRLF": {
			"type": "boolean"
		},
		"richCardWrapTitle": {
			"description": "Applies to subtitles as well",
			"type": "boolean"
		},
		"rootHeight": {
			"type": "string"
		},
		"rootWidth": {
			"type": "string"
		},
		"rootZIndex": {
			"description": "\"z-index\" for the root container of Web Chat. This will form a new stacking context so \"z-index\" used in children won't pollute.",
			"type": "number"
		}, 
		"hideScrollToEndButton": {
			"type": "boolean"
		},
		"hideSendBox": {
			"type": "boolean"
		},
		"hideUploadButton": {
			"type": "boolean"
		},
		"microphoneButtonColorOnDictate": {
			"$role": "color",
			"type": "string"
		},
		"sendBoxBackground": {
			"$role": "color",
			"type": "string"
		},
		"sendBoxButtonColor": {
			"$role": "color",
			"type": "string"
		},
		"sendBoxButtonColorOnDisabled": {
			"$role": "color",
			"type": "string"
		},
		"sendBoxButtonColorOnFocus": {
			"$role": "color",
			"type": "string"
		},
		"sendBoxButtonColorOnHover": {
			"$role": "color",
			"type": "string"
		},
		"sendBoxDisabledTextColor": {
			"$role": "color",
			"type": "string"
		},
		"sendBoxHeight": {
			"type": "number"
		},
		"sendBoxMaxHeight": {
			"type": "number"
		},
		"sendBoxTextColor": {
			"$role": "color",
			"type": "string"
		},
		
		"sendBoxPlaceholderColor": {
			"$role": "color",
			"description": "defaults to subtle",
			"type": "string"
		},
		"sendBoxTextWrap": {
			"type": "boolean"
		},
		"showSpokenText": {
			"description": "Visually show spoken text",
			"type": "boolean"
		},
		"suggestedActionBackground": {
			"$role": "color",
			"type": "string"
		},
		"suggestedActionBorderColor": {
			"$role": "color",
			"description": "defaults to accent",
			"type": "string"
		},
		"suggestedActionBorderRadius": {
			"type": "number"
		},
		"suggestedActionBorderStyle": {
			"type": "string",
			"enum": [
				"dotted",
				"dashed",
				"solid",
				"double",
				"groove",
				"ridge",
				"inset",
				"outset",
				"none",
				"hidden",
				"mix"
			]
		},
		"suggestedActionBorderWidth": {
			"type": "number"
		},
		"suggestedActionDisabledBackground": {
			"$role": "color",
			"description": "",
			"type": "string"
		},
		"suggestedActionDisabledBorderColor": {
			"$role": "color",
			"type": "string"
		},
		"suggestedActionDisabledBorderStyle": {
			"type": "string",
			"enum": [
				"dotted",
				"dashed",
				"solid",
				"double",
				"groove",
				"ridge",
				"inset",
				"outset",
				"none",
				"hidden",
				"mix"
			]
		},
		"suggestedActionDisabledTextColor": {
			"$role": "color",
			"description": "defaults to subtle",
			"type": "string"
		},
		"suggestedActionLayout": {
			"type": "string",
			"enum": [
				"carousel",
				"stacked"
			]
		}
    }
};

const uiOptions = {
	fieldsets: [
		{ title: 'Avatar', fields: ['avatarBorderRadius', 'avatarSize', 'botAvatarBackgroundColor', 'botAvatarImage', 'botAvatarInitials', 'userAvatarBackgroundColor', 'userAvatarImage', 'userAvatarInitials', 'showAvatarInGroup'] },
		{ title: 'Bubble', fields: ['bubbleBackground'] },
		{ title: 'Markdown', fields: ['markdownRespectCRLF'] },
		{ title: 'Send box', fields: ['hideSendBox', 'hideUploadButton'] },
		{ title: 'Suggested actions', fields: ['suggestedActionBackground', 'suggestedActionBorder'] },
		{ title: 'Other' }]
};

export const WebChatDesigner: React.FC = () => {
	const [styleOptions, setStyleOptions] = useState({});

	return (
		<div style={{ display: 'flex', height: '100%' }}>
			<div style={{ flex: 1, background: 'lightgrey', textAlign: 'center' }}>
				<ReactWebChat styleOptions={styleOptions} />
			</div>
			<div style={{ overflowY: 'auto' }}>
				<AdaptiveForm formData={styleOptions} onChange={setStyleOptions} schema={schema} uiOptions={uiOptions} />
			</div>
		</div>

	)
}

export default WebChatDesigner;

Playground to do items:

  • Reliable connection

  • Speech

  • Voice gender preference

  • Make all defaultStyleOptions configurable in the side panel

    • Color / padding / root
    • Fonts
    • Avatar
    • Bubble
    • Markdown
    • Rich cards
    • Send box
    • Show spoken text
    • Suggested actions
    • Timestamp
    • Transcript overlay buttons
    • Video
    • Connectivity
    • Typing animation
    • Spinner animation
    • Upload thumbnail
    • Toast
    • Emoji
    • Use fluent to intuitively group different sections/props
    • Use fluent to add info icons w/ descriptions / suggested commands
    • Add a section in a side panel with a note that says 'Selecting these options will restart Web Chat':
      • Changing username
      • Changing userID
    • Set up @emotion/core properly
  • Add buttons to manually test Mock Bot commands?

  • use utils to indicate what browser we're using

  • DARK MODE

  • Middleware: Connection status always visible

  • Middleware: <ScreenReaderText> components visible

  • Store whether last token fetch was from local or official MockBot

  • Change alerts and console logs to toasts

  • Enable search

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by comparing the Web Chat Editor repository and hosted app with the Web Chat Designer example and the existing playground checklist. Document overlapping work, define the playground scope for the demo app, Composer extension, and future hosting surfaces, and record actionable alignment decisions as the completed plan.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend, web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.