diff --git a/CHANGELOG.md b/CHANGELOG.md
index 06794c77cc..22346a0dd4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -81,6 +81,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- Resolves [#3777](https://github.com/microsoft/BotFramework-WebChat/issues/3777). Added a new `adaptiveCardsParserMaxVersion` style options for selecting the maximum supported version when parsing an Adaptive Cards, by [@compulim](https://github.com/compulim) in PR [#3778](https://github.com/microsoft/BotFramework-WebChat/pull/3778)
+- Resolves [#2100](https://github.com/microsoft/BotFramework-WebChat/issues/2100). Add types declarations for Style Options in api bundle, by [@corinagum](https://github.com/corinagum), in PR [#3818](https://github.com/microsoft/BotFramework-WebChat/pull/3818)
### Fixed
diff --git a/__tests__/.eslintrc b/__tests__/.eslintrc
index 01dcb648fd..e879ad0fb7 100644
--- a/__tests__/.eslintrc
+++ b/__tests__/.eslintrc
@@ -2,5 +2,7 @@ globals:
runHTMLTest: readonly
ignorePatterns:
- "**/*.js"
+- "**/*.ts"
+- "**/*.tsx"
- "!/html/__jest__/*.js"
- "!/setup/*.js"
diff --git a/__tests__/adaptiveCards.js b/__tests__/adaptiveCards.js
index a6f0f1a794..38ffb3c30d 100644
--- a/__tests__/adaptiveCards.js
+++ b/__tests__/adaptiveCards.js
@@ -7,7 +7,6 @@ import scrollToBottomCompleted from './setup/conditions/scrollToBottomCompleted'
import uiConnected from './setup/conditions/uiConnected';
import createAdaptiveCardsHostConfig from '../packages/bundle/src/adaptiveCards/Styles/adaptiveCardHostConfig';
-import defaultStyleOptions from '../packages/component/src/Styles/defaultStyleOptions';
// selenium-webdriver API doc:
// https://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebDriver.html
@@ -57,7 +56,7 @@ test('action styles', async () => {
});
test('breakfast card with custom host config', async () => {
- const adaptiveCardHostConfig = createAdaptiveCardsHostConfig({ ...defaultStyleOptions, bubbleTextColor: '#FF0000' });
+ const adaptiveCardHostConfig = createAdaptiveCardsHostConfig({ bubbleTextColor: '#FF0000' });
const { driver, pageObjects } = await setupWebDriver({
props: {
@@ -179,7 +178,7 @@ test('Inputs card with custom style options and submit action', async () => {
props: {
styleOptions: {
cardPushButtonBackgroundColor: '#ee0606',
- cardPushButtonTextColor:'#ee0606'
+ cardPushButtonTextColor: '#ee0606'
}
}
});
diff --git a/__tests__/types/__typescript__/.gitignore b/__tests__/types/__typescript__/.gitignore
new file mode 100644
index 0000000000..c981789ba1
--- /dev/null
+++ b/__tests__/types/__typescript__/.gitignore
@@ -0,0 +1,4 @@
+dirNumber.js
+dirString.js
+styleOptionsAccent.js
+styleOptionsCardEmph.js
\ No newline at end of file
diff --git a/__tests__/types/__typescript__/dirNumber.tsx b/__tests__/types/__typescript__/dirNumber.tsx
new file mode 100644
index 0000000000..1f867e3ba3
--- /dev/null
+++ b/__tests__/types/__typescript__/dirNumber.tsx
@@ -0,0 +1,10 @@
+import ReactWebChat, { createStyleSet, StyleOptions } from '../../../packages/bundle/lib/index';
+
+function main() {
+ const styleOptions: StyleOptions = { accent: 'black', cardEmphasisBackgroundColor: 'orange' };
+
+ createStyleSet(styleOptions);
+
+ // "dir" of type number should fail
+ return ;
+}
diff --git a/__tests__/types/__typescript__/dirString.tsx b/__tests__/types/__typescript__/dirString.tsx
new file mode 100644
index 0000000000..cd7e894833
--- /dev/null
+++ b/__tests__/types/__typescript__/dirString.tsx
@@ -0,0 +1,10 @@
+import ReactWebChat, { createStyleSet, StyleOptions } from '../../../packages/bundle/lib/index';
+
+function main() {
+ const styleOptions: StyleOptions = { accent: 'black', cardEmphasisBackgroundColor: 'orange' };
+
+ createStyleSet(styleOptions);
+
+ // Verify: "dir" of type string should pass
+ return ;
+}
diff --git a/__tests__/types/__typescript__/styleOptionsAccent.tsx b/__tests__/types/__typescript__/styleOptionsAccent.tsx
new file mode 100644
index 0000000000..5c88b8480f
--- /dev/null
+++ b/__tests__/types/__typescript__/styleOptionsAccent.tsx
@@ -0,0 +1,10 @@
+import ReactWebChat, { createStyleSet, StyleOptions } from '../../../packages/bundle/lib/index-minimal';
+
+function main() {
+ const styleOptions: StyleOptions = { accent: 'black' };
+
+ createStyleSet(styleOptions);
+
+ // Verify: Setting "accent" must should pass.
+ return ;
+}
diff --git a/__tests__/types/__typescript__/styleOptionsCardEmph.tsx b/__tests__/types/__typescript__/styleOptionsCardEmph.tsx
new file mode 100644
index 0000000000..2d20c3f1f7
--- /dev/null
+++ b/__tests__/types/__typescript__/styleOptionsCardEmph.tsx
@@ -0,0 +1,10 @@
+import ReactWebChat, { createStyleSet, StyleOptions } from '../../../packages/bundle/lib/index-minimal';
+
+function main() {
+ const styleOptions: StyleOptions = { cardEmphasisBackgroundColor: 'orange' };
+
+ createStyleSet(styleOptions);
+
+ // Verify: Setting "cardEmphasisBackgroundColor" using minimal bundle must fail.
+ return ;
+}
diff --git a/__tests__/types/typesCheck.js b/__tests__/types/typesCheck.js
new file mode 100644
index 0000000000..da708ee51b
--- /dev/null
+++ b/__tests__/types/typesCheck.js
@@ -0,0 +1,54 @@
+const ts = require('typescript');
+const path = require('path');
+
+function compile(...filenames) {
+ const program = ts.createProgram(filenames, {
+ allowSyntheticDefaultImports: true,
+ jsx: 'react',
+ noEmit: true,
+ skipLibCheck: true,
+ });
+
+ const emitResult = program.emit();
+ const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
+ const errors = [];
+
+ allDiagnostics.forEach(diagnostic => {
+ if (diagnostic.file) {
+ const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
+ const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
+ errors.push(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
+ } else {
+ errors.push(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'));
+ }
+ });
+
+ return errors;
+};
+
+
+it('should pass dir as string', () => {
+ const dirStringErrors = compile(path.join(__dirname, './__typescript__/dirString.tsx'));
+
+ expect(dirStringErrors).toHaveProperty('length', 0);
+});
+
+it('should fail on dir as number', () => {
+ const dirNumErrors = compile(path.join(__dirname, './__typescript__/dirNumber.tsx'));
+
+ expect(dirNumErrors).toHaveProperty('length', 1);
+ expect(dirNumErrors[0]).toEqual(expect.stringContaining(`Type 'number' is not assignable to type '"ltr" | "rtl" | "auto"'`));
+});
+
+it('should fail on accent', () => {
+ const accentErrors = compile(path.join(__dirname, './__typescript__/styleOptionsAccent.tsx'));
+
+ expect(accentErrors).toHaveProperty('length', 0);
+});
+
+it('should pass on cardEmphasisBackgroundColor', () => {
+ const cardEmphErrors = compile(path.join(__dirname, './__typescript__/styleOptionsCardEmph.tsx'));
+
+ expect(cardEmphErrors).toHaveProperty('length', 1);
+ expect(cardEmphErrors[0]).toEqual(expect.stringContaining(`Type '{ cardEmphasisBackgroundColor: string; }' is not assignable to type 'StyleOptions'`));
+});
diff --git a/docs/API.md b/docs/API.md
index 74dc87058c..f2ab416be4 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -20,7 +20,7 @@ There are several properties that you might pass into your Web Chat React Compon
| `renderMarkdown` | Change the default Markdown renderer object. |
| `sendTypingIndicator` | Display a typing signal from the user to the bot to indicate that the user is not idling. |
| `store` | Specify a custom store, e.g. for adding programmatic activity to the bot. |
-| `styleOptions` | Object that stores customization values for your styling of Web Chat. For the complete list of (frequently updated) default style options, please see the [defaultStyleOptions.js](https://github.com/microsoft/BotFramework-WebChat/blob/master/packages/component/src/Styles/defaultStyleOptions.js) file. |
+| `styleOptions` | Object that stores customization values for your styling of Web Chat. For the complete list of (frequently updated) default style options, please see the [defaultStyleOptions.ts](https://github.com/microsoft/BotFramework-WebChat/blob/master/packages/api/src/defaultStyleOptions.ts) and [adaptiveCards/defaultStyleOptions.ts](https://github.com/microsoft/BotFramework-WebChat/blob/master/packages/bundle/src/adaptiveCards/defaultStyleOptions.ts) file. |
| `styleSet` | The non-recommended way of overriding styles. |
| `userID` | Specify a userID. There are two ways to specify the `userID`: in props, or in the token when generating the token call (`createDirectLine()`). If both methods are used to specify the userID, the token userID property will be used, and a `console.warn` will appear during runtime. If the `userID` is provided via props but is prefixed with `'dl'`, e.g. `'dl_1234'`, the value will be thrown and a new `ID` generated. If `userID` is not specified, it will default to a random user ID. Multiple users sharing the same user ID is not recommended; their user state will be shared, which creates a security risk when authenticating. |
| `username` | Specify a username. |
diff --git a/docs/HOOKS.md b/docs/HOOKS.md
index 016489b778..3f94cc524e 100644
--- a/docs/HOOKS.md
+++ b/docs/HOOKS.md
@@ -1131,7 +1131,7 @@ useStyleOptions(): [StyleOptions]
This hook will return the style options. UI components should honor the styling preferences.
-The value is not the same as the props. Web Chat will merge the style options passed in props with default values specified in [`defaultStyleOptions.js`](https://github.com/microsoft/BotFramework-WebChat/blob/master/packages/component/src/Styles/defaultStyleOptions.js).
+The value is not the same as the props. Web Chat will merge the style options passed in props with default values specified in [`defaultStyleOptions.ts`](https://github.com/microsoft/BotFramework-WebChat/blob/master/packages/api/src/defaultStyleOptions.ts) and [`adaptiveCards/defaultStyleOptions.ts`](https://github.com/microsoft/BotFramework-WebChat/blob/master/packages/bundle/src/adaptiveCards/defaultStyleOptions.ts) when Adaptive Cards is enabled.
To modify the value of `styleOptions` state, change the props you pass to Web Chat.
diff --git a/jest.config.js b/jest.config.js
index 5eab9506d8..4aeabd93ac 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -76,6 +76,7 @@ module.exports = {
'/__tests__/html/assets',
'/__tests__/html/__dist__',
'/__tests__/html/__jest__',
+ '/__tests__/types/__typescript__',
'/__tests__/setup/',
'/packages/directlinespeech/__tests__/utilities/',
'/packages/playground/',
diff --git a/package-lock.json b/package-lock.json
index 3da5daf530..6526aff9cb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13697,6 +13697,12 @@
"is-typedarray": "^1.0.0"
}
},
+ "typescript": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz",
+ "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==",
+ "dev": true
+ },
"uglify-js": {
"version": "3.11.5",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.5.tgz",
diff --git a/package.json b/package.json
index cd52430491..e663f82ff8 100644
--- a/package.json
+++ b/package.json
@@ -70,6 +70,7 @@
"serve": "^11.3.2",
"serve-handler": "^6.1.3",
"strip-ansi": "^6.0.0",
+ "typescript": "^4.2.3",
"xmlbuilder": "^15.1.1"
},
"dependencies": {}
diff --git a/packages/api/.eslintrc.yml b/packages/api/.eslintrc.yml
index 3d1c9cc36d..1046d75635 100644
--- a/packages/api/.eslintrc.yml
+++ b/packages/api/.eslintrc.yml
@@ -3,6 +3,9 @@ extends:
plugins:
- prettier
- react-hooks
+- '@typescript-eslint/eslint-plugin'
+parser:
+ '@typescript-eslint/parser'
rules:
# plugins
prettier/prettier: error
@@ -89,3 +92,11 @@ rules:
react/jsx-wrap-multilines: error # Conflict with no-extra-parens
react-hooks/rules-of-hooks: error
react-hooks/exhaustive-deps: warn
+
+ # TypeScript
+
+ # The correct way to use with typescript-eslint is to disable the core version.
+ # https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-use-before-define.md#how-to-use
+ no-use-before-define: off
+ '@typescript-eslint/no-use-before-define':
+ - error
diff --git a/packages/api/babel.config.json b/packages/api/babel.config.json
index e43758f909..b84cdf97d7 100644
--- a/packages/api/babel.config.json
+++ b/packages/api/babel.config.json
@@ -5,6 +5,7 @@
"plugins": ["babel-plugin-istanbul"]
}
},
+ "ignore": ["src/index.tsx"],
"overrides": [
{
"plugins": [],
diff --git a/packages/api/package-lock.json b/packages/api/package-lock.json
index 25f4eabe12..8768b66439 100644
--- a/packages/api/package-lock.json
+++ b/packages/api/package-lock.json
@@ -3594,6 +3594,32 @@
"upath": "^1.1.1"
}
},
+ "@nodelib/fs.scandir": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
+ "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.4",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz",
+ "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz",
+ "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.4",
+ "fastq": "^1.6.0"
+ }
+ },
"@types/json-schema": {
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
@@ -3627,6 +3653,188 @@
"csstype": "^3.0.2"
}
},
+ "@typescript-eslint/eslint-plugin": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.19.0.tgz",
+ "integrity": "sha512-CRQNQ0mC2Pa7VLwKFbrGVTArfdVDdefS+gTw0oC98vSI98IX5A8EVH4BzJ2FOB0YlCmm8Im36Elad/Jgtvveaw==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/experimental-utils": "4.19.0",
+ "@typescript-eslint/scope-manager": "4.19.0",
+ "debug": "^4.1.1",
+ "functional-red-black-tree": "^1.0.1",
+ "lodash": "^4.17.15",
+ "regexpp": "^3.0.0",
+ "semver": "^7.3.2",
+ "tsutils": "^3.17.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ }
+ }
+ },
+ "@typescript-eslint/experimental-utils": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.19.0.tgz",
+ "integrity": "sha512-9/23F1nnyzbHKuoTqFN1iXwN3bvOm/PRIXSBR3qFAYotK/0LveEOHr5JT1WZSzcD6BESl8kPOG3OoDRKO84bHA==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.3",
+ "@typescript-eslint/scope-manager": "4.19.0",
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/typescript-estree": "4.19.0",
+ "eslint-scope": "^5.0.0",
+ "eslint-utils": "^2.0.0"
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.19.0.tgz",
+ "integrity": "sha512-/uabZjo2ZZhm66rdAu21HA8nQebl3lAIDcybUoOxoI7VbZBYavLIwtOOmykKCJy+Xq6Vw6ugkiwn8Js7D6wieA==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/scope-manager": "4.19.0",
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/typescript-estree": "4.19.0",
+ "debug": "^4.1.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "@typescript-eslint/scope-manager": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.19.0.tgz",
+ "integrity": "sha512-GGy4Ba/hLXwJXygkXqMzduqOMc+Na6LrJTZXJWVhRrSuZeXmu8TAnniQVKgj8uTRKe4igO2ysYzH+Np879G75g==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/visitor-keys": "4.19.0"
+ }
+ },
+ "@typescript-eslint/types": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.19.0.tgz",
+ "integrity": "sha512-A4iAlexVvd4IBsSTNxdvdepW0D4uR/fwxDrKUa+iEY9UWvGREu2ZyB8ylTENM1SH8F7bVC9ac9+si3LWNxcBuA==",
+ "dev": true
+ },
+ "@typescript-eslint/typescript-estree": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.19.0.tgz",
+ "integrity": "sha512-3xqArJ/A62smaQYRv2ZFyTA+XxGGWmlDYrsfZG68zJeNbeqRScnhf81rUVa6QG4UgzHnXw5VnMT5cg75dQGDkA==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/visitor-keys": "4.19.0",
+ "debug": "^4.1.1",
+ "globby": "^11.0.1",
+ "is-glob": "^4.0.1",
+ "semver": "^7.3.2",
+ "tsutils": "^3.17.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ }
+ }
+ },
+ "@typescript-eslint/visitor-keys": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.19.0.tgz",
+ "integrity": "sha512-aGPS6kz//j7XLSlgpzU2SeTqHPsmRYxFztj2vPuMMFJXZudpRSehE3WCV+BaxwZFvfAqMoSd86TEuM0PQ59E/A==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.19.0",
+ "eslint-visitor-keys": "^2.0.0"
+ }
+ },
"@webassemblyjs/ast": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
@@ -4013,6 +4221,12 @@
}
}
},
+ "array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true
+ },
"array-unique": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
@@ -4437,6 +4651,15 @@
"integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
"optional": true
},
+ "bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "optional": true,
+ "requires": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -5421,6 +5644,15 @@
}
}
},
+ "dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "requires": {
+ "path-type": "^4.0.0"
+ }
+ },
"doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@@ -6291,6 +6523,74 @@
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
"dev": true
},
+ "fast-glob": {
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
+ "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.0",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.2",
+ "picomatch": "^2.2.1"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -6302,6 +6602,15 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
+ "fastq": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz",
+ "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
"figgy-pudding": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
@@ -6316,6 +6625,12 @@
"flat-cache": "^3.0.4"
}
},
+ "file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "optional": true
+ },
"filewatcher": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/filewatcher/-/filewatcher-3.0.1.tgz",
@@ -6648,6 +6963,34 @@
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
},
+ "globby": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz",
+ "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==",
+ "dev": true,
+ "requires": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.1.1",
+ "ignore": "^5.1.4",
+ "merge2": "^1.3.0",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ }
+ }
+ },
"graceful-fs": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
@@ -7443,6 +7786,12 @@
"readable-stream": "^2.0.1"
}
},
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
+ },
"micromatch": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@@ -7579,6 +7928,12 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
+ "nan": {
+ "version": "2.14.2",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
+ "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+ "optional": true
+ },
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -8306,6 +8661,12 @@
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
},
+ "path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true
+ },
"pbkdf2": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
@@ -8327,8 +8688,7 @@
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
- "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
- "optional": true
+ "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg=="
},
"pify": {
"version": "4.0.1",
@@ -8514,6 +8874,12 @@
"resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
"integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
},
+ "queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true
+ },
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -8825,6 +9191,12 @@
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
},
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true
+ },
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
@@ -8842,6 +9214,15 @@
"inherits": "^2.0.1"
}
},
+ "run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "requires": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
"run-queue": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
@@ -9763,6 +10144,15 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q=="
},
+ "tsutils": {
+ "version": "3.21.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+ "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ }
+ },
"tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -10049,7 +10439,11 @@
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
- "optional": true
+ "optional": true,
+ "requires": {
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
+ }
}
}
},
diff --git a/packages/api/package.json b/packages/api/package.json
index df1977960a..921f273a65 100644
--- a/packages/api/package.json
+++ b/packages/api/package.json
@@ -3,6 +3,7 @@
"version": "0.0.0-0",
"description": "React DOM component of botframework-webchat",
"main": "lib/index.js",
+ "typings": "lib/index.d.ts",
"publishConfig": {
"access": "public"
},
@@ -37,6 +38,8 @@
"@babel/preset-typescript": "^7.13.0",
"@types/node": "^14.14.35",
"@types/react": "^16.9.55",
+ "@typescript-eslint/eslint-plugin": "^4.19.0",
+ "@typescript-eslint/parser": "^4.19.0",
"babel-plugin-istanbul": "^6.0.0",
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
"cldr-data": "^36.0.0",
diff --git a/packages/api/src/StyleOptions.ts b/packages/api/src/StyleOptions.ts
new file mode 100644
index 0000000000..e0f6a6587b
--- /dev/null
+++ b/packages/api/src/StyleOptions.ts
@@ -0,0 +1,494 @@
+type StyleOptions = {
+ /**
+ * Basic styling
+ */
+
+ /** Web Chat component accent color */
+ accent?: string;
+
+ /**
+ * Transcript background color
+ */
+ backgroundColor?: string;
+
+ /**
+ * Secondary component color
+ */
+ subtle?: string;
+
+ /**
+ * Default padding used in most visual components
+ */
+ paddingRegular?: number;
+
+ /**
+ * Padding used for suggestedAction buttons
+ */
+ paddingWide?: number;
+
+ /**
+ Transition for Bubble, Carousel, and StackedLayout
+ */
+ transitionDuration?: string;
+
+ /**
+ * Fonts
+ * Default font size will be inherited from the host app
+ */
+
+ /**
+ * Font size used for secondary components such as sendStatus
+ */
+ fontSizeSmall?: number | string;
+
+ /**
+ * Font used for ErrorBox
+ * comma-space separated string
+ */
+ monospaceFont?: string;
+
+ /**
+ * Font used in most visual components
+ * comma-space separated string
+ */
+ primaryFont?: string;
+
+ rootHeight?: number | string;
+
+ rootWidth?: number | string;
+
+ /**
+ * "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.
+ */
+ rootZIndex?: number;
+
+ /**
+ * Avatar styling
+ */
+
+ /**
+ * Border radius used for both bot and user avatar
+ */
+ avatarBorderRadius?: number | string;
+
+ /**
+ * Height and width of avatar
+ */
+ avatarSize?: number;
+
+ /**
+ * Background color defaults to accent
+ */
+ botAvatarBackgroundColor?: string;
+
+ /**
+ * URL string. Can be data URI or blob
+ * botAvatarInitials must be set to empty string
+ */
+ botAvatarImage?: string;
+
+ /**
+ * Typically rendered as two letters, e.g. 'WC'
+ * Empty string is required when setting botAvatarImage
+ */
+ botAvatarInitials?: string;
+
+ /**
+ * Background color defaults to accent
+ */
+ userAvatarBackgroundColor?: string;
+
+ /**
+ * URL string. Can be data URI or blob
+ * userAvatarInitials must be set to empty string
+ */
+ userAvatarImage?: string;
+
+ /**
+ * Typically rendered as two letters, i.e. 'WC'
+ * Empty string is required when setting userAvatarImage
+ */
+ userAvatarInitials?: string;
+
+ /**
+ * Avatar grouping can be set at 3 different levels:
+ * Show avatar on activities sharing the same sender ('sender')
+ * Show avatar on activities sharing the same status ('status'; default)
+ * Show avatar on every activity (true)
+ */
+ showAvatarInGroup?: true | 'sender' | 'status';
+
+ /**
+ * Bubble styling
+ * 'Bubble' refers to the container of the activit(ies) from the bot and user. Below, non-'fromUser' props refer to styling for the bot activities.
+ */
+
+ bubbleBackground?: string;
+ bubbleBorderColor?: string;
+ bubbleBorderRadius?: number;
+ bubbleBorderStyle?: string;
+ bubbleBorderWidth?: number;
+ bubbleFromUserBackground?: string;
+ bubbleFromUserBorderColor?: string;
+ bubbleFromUserBorderRadius?: number;
+ bubbleFromUserBorderStyle?: string;
+ bubbleFromUserBorderWidth?: number;
+
+ /**
+ * Nub offset 'bottom' will render nub at the bottom
+ * A positive or negative number will shift nub offset up/down
+ * "top" is equivalent to positive zero.
+ * "bottom" is equivalent to negative zero.
+ */
+ bubbleFromUserNubOffset?: number | 'bottom' | 'top';
+
+ /**
+ * Nub size 0 will render a sharp corner
+ */
+ bubbleFromUserNubSize?: number;
+
+ bubbleFromUserTextColor?: string;
+ bubbleImageHeight?: number;
+ bubbleMaxWidth?: number;
+ bubbleMinHeight?: number;
+ bubbleMinWidth?: number;
+
+ /**
+ * Nub offset ''bottom' will render nub at the bottom
+ * A positive or negative number will shift nub offset up/down
+ * "top" is equivalent to positive zero.
+ * "bottom" is equivalent to negative zero.
+ */
+ bubbleNubOffset?: number | 'bottom' | 'top';
+
+ /**
+ * Nub size 0 will render a sharp corner
+ */
+ bubbleNubSize?: number;
+
+ bubbleTextColor?: string;
+
+ messageActivityWordBreak?: 'normal' | 'break-all' | 'break-word' | 'keep-all';
+
+ /**
+ * Connectivity UI styling
+ */
+
+ connectivityIconPadding?: number;
+ connectivityMarginLeftRight?: number;
+ connectivityMarginTopBottom?: number;
+ connectivityTextSize?: number | string;
+ failedConnectivity?: number | string;
+ slowConnectivity?: string;
+ notificationText?: string;
+
+ /**
+ * Slow connection status will render after x amount of time with no service response
+ */
+ slowConnectionAfter?: number;
+
+ /**
+ * Emoji styling
+ * If true, Web Chat's default set of emoji will be enabled. See patchStyleOptions.js for default list.
+ * A custom object will enable unicode emoji specified by the developer.
+ * key: emoticon
+ * value: unicode emoji
+ */
+ emojiSet?: boolean | Record;
+
+ /**
+ * Live region - Accessibility
+ * New activities will be rendered in the non-visual live region and removed after a certain amount of time. Modify this property to change fade time.
+ */
+ internalLiveRegionFadeAfter?: number;
+
+ /**
+ * Markdown styling
+ * Parse markdown to ensure carriage return is respected
+ */
+ markdownRespectCRLF?: boolean;
+
+ /**
+ * Assign new image for anchor links to indicate external
+ */
+
+ markdownExternalLinkIconImage?: string;
+ /**
+ * Scroll behavior styling
+ */
+
+ /**
+ * Prevent scroll to end button from rendering
+ */
+ hideScrollToEndButton?: boolean;
+
+ /**
+ * Snap to activity to 'snap-point'
+ * If true, scrolling will pause after 1 activity is received.
+ * Specifying a number will pause after X number of activities
+ */
+ autoScrollSnapOnActivity?: boolean | number;
+
+ /**
+ * Specify number of pixels to overscroll or underscroll after pause
+ */
+ autoScrollSnapOnActivityOffset?: number;
+
+ /**
+ * If true, scrolling will pause after activities have filled the page.
+ * Specifying a number (0 to 1) will pause after % of page is filled
+ */
+ autoScrollSnapOnPage?: boolean | number;
+
+ /**
+ * Specify number of pixels to overscroll or underscroll after pause
+ */
+ autoScrollSnapOnPageoffset?: number;
+
+ /**
+ * Send box styling
+ */
+
+ hideSendBox?: boolean;
+ hideUploadButton?: boolean;
+ microphoneButtonColorOnDictate?: string;
+ sendBoxBackground?: string;
+
+ /**
+ * Button color defaults to subtle
+ */
+ sendBoxButtonColor?: string;
+
+ sendBoxButtonColorOnDisabled?: string;
+ sendBoxButtonColorOnFocus?: string;
+ sendBoxButtonColorOnHover?: string;
+
+ /**
+ * Disabled text color defaults to subtle
+ */
+ sendBoxDisabledTextColor?: string;
+
+ sendBoxHeight?: number | string;
+ sendBoxMaxHeight?: number | string;
+ sendBoxTextColor?: string;
+ sendBoxBorderBottom?: number | string;
+ sendBoxBorderLeft?: number | string;
+ sendBoxBorderRight?: number | string;
+ sendBoxBorderTop?: number | string;
+ sendBoxPlaceholderColor?: string;
+ sendBoxTextWrap?: boolean;
+ sendBoxButtonAlignment?: 'bottom' | 'stretch' | 'top';
+
+ /**
+ * Show spoken text
+ */
+ showSpokenText?: boolean;
+
+ /**
+ * Spinner animation styling
+ */
+
+ spinnerAnimationBackgroundImage?: string;
+ spinnerAnimationHeight?: number | string;
+ spinnerAnimationWidth?: number | string;
+ spinnerAnimationPadding?: number | string;
+
+ /**
+ * Suggested Actions
+ */
+
+ suggestedActionBackground?: string;
+
+ /**
+ * Border color defaults to accent.
+ */
+ suggestedActionBorderColor?: string;
+
+ suggestedActionBorderRadius?: number | string;
+ suggestedActionBorderStyle?: string;
+ suggestedActionBorderWidth?: number | string;
+
+ /**
+ * Disabled background defaults to suggestedActionBackground
+ */
+ suggestedActionDisabledBackground?: string;
+
+ suggestedActionDisabledBorderColor?: string;
+ suggestedActionDisabledBorderStyle?: string;
+ suggestedActionDisabledBorderWidth?: number | string;
+
+ /**
+ * Disabled text color defaults to subtle
+ */
+ suggestedActionDisabledTextColor?: string;
+
+ suggestedActionHeight?: number | string;
+ suggestedActionImageHeight?: number | string;
+ suggestedActionLayout?: 'carousel' | 'flow' | 'stacked';
+ suggestedActionTextColor?: string;
+
+ /**
+ * Suggested actions carousel layout
+ */
+
+ /**
+ * Cursor when mouseover on flipper
+ */
+ suggestedActionsCarouselFlipperCursor?: string;
+
+ /**
+ * Flipper bounding box size
+ */
+ suggestedActionsCarouselFlipperBoxWidth?: number;
+
+ /**
+ * Flipper button's visible size
+ */
+ suggestedActionsCarouselFlipperSize?: number;
+
+ /**
+ * Suggested actions flow layout
+ * Default value is 'auto',
+ */
+ suggestedActionsFlowMaxHeight?: undefined;
+
+ /**
+ * Suggested actions stacked layout
+ */
+
+ /**
+ * Stacked height container's max height. Default value is 'auto'
+ */
+ suggestedActionsStackedHeight?: number | 'auto';
+
+ /**
+ * Stacked overflow default value is 'auto
+ */
+ suggestedActionsStackedOverflow?: 'string';
+
+ /**
+ * Button max height default value is 100% if suggestedActionsStackedLayoutButtonTextWrap is true
+ */
+ suggestedActionsStackedLayoutButtonMaxHeight?: number | string;
+
+ /**
+ * Button Text Wrap, if set to true, will wrap long text in buttons in STACKED mode ONLY
+ */
+ suggestedActionsStackedLayoutButtonTextWrap?: boolean;
+
+ /**
+ * Timestamp
+ */
+
+ groupTimestamp?: boolean;
+ sendTimeout?: number;
+ sendTimeoutForAttachments?: number;
+
+ /**
+ * Timestamp color default value is subtle
+ */
+ timestampColor?: string;
+
+ timestampFormat?: 'absolute' | 'relative';
+
+ /**
+ * Transcript styling
+ */
+
+ transcriptTerminatorBackgroundColor?: string;
+ transcriptTerminatorBorderRadius?: number | string;
+ transcriptTerminatorColor?: string;
+ transcriptTerminatorFontSize?: number | string;
+
+ transcriptActivityVisualKeyboardIndicatorColor?: string;
+ transcriptActivityVisualKeyboardIndicatorStyle?: string;
+ transcriptActivityVisualKeyboardIndicatorWidth?: number | string;
+
+ transcriptVisualKeyboardIndicatorColor?: string;
+ transcriptVisualKeyboardIndicatorStyle?: string;
+ transcriptVisualKeyboardIndicatorWidth?: number | string;
+
+ /**
+ * Transcript overlay button
+ * e.g. carousel and suggested action flippers, scroll to bottom, etc.
+ */
+
+ newMessagesButtonFontSize?: number | string;
+ transcriptOverlayButtonBackground?: string;
+ transcriptOverlayButtonBackgroundOnDisabled?: string;
+ transcriptOverlayButtonBackgroundOnFocus?: string;
+ transcriptOverlayButtonBackgroundOnHover?: string;
+ transcriptOverlayButtonColor?: string;
+ transcriptOverlayButtonColorOnDisabled?: string;
+
+ /**
+ * Default value is transcriptOverlayButtonColor
+ */
+ transcriptOverlayButtonColorOnFocus?: string;
+
+ /**
+ * Default value is transcriptOverlayButtonColor
+ */
+ transcriptOverlayButtonColorOnHover?: string;
+
+ /**
+ * Toast UI
+ */
+
+ /**
+ * New debounce timeout value only affects new notifications.
+ */
+ notificationDebounceTimeout?: number;
+
+ hideToaster?: boolean;
+ toasterHeight?: number | string;
+ toasterMaxHeight?: number | string;
+ toasterSingularMaxHeight?: number | string;
+ toastFontSize?: number | string;
+ toastIconWidth?: number | string;
+ toastSeparatorColor?: string;
+ toastTextPadding?: number | string;
+
+ toastErrorBackgroundColor?: string;
+ toastErrorColor?: string;
+ toastInfoBackgroundColor?: string;
+ toastInfoColor?: string;
+ toastSuccessBackgroundColor?: string;
+ toastSuccessColor?: string;
+ toastWarnBackgroundColor?: string;
+ toastWarnColor?: string;
+
+ /**
+ * Typing animation
+ */
+
+ typingAnimationBackgroundImage?: string;
+ typingAnimationDuration?: number;
+ typingAnimationHeight?: number | string;
+ typingAnimationWidth?: number | string;
+
+ /**
+ * Upload thumbnail
+ */
+
+ enableUploadThumbnail?: boolean;
+ uploadThumbnailContentType?: string;
+ uploadThumbnailHeight?: number | string;
+ uploadThumbnailQuality?: number;
+ uploadThumbnailWidth?: number | string;
+
+ /**
+ * Video
+ */
+
+ videoHeight?: number | string;
+};
+
+type StrictStyleOptions = Required & {
+ bubbleFromUserNubOffset: number;
+ bubbleNubOffset: number;
+ emojiSet: false | Record;
+};
+
+export default StyleOptions;
+export { StrictStyleOptions };
diff --git a/packages/api/src/defaultStyleOptions.js b/packages/api/src/defaultStyleOptions.ts
similarity index 59%
rename from packages/api/src/defaultStyleOptions.js
rename to packages/api/src/defaultStyleOptions.ts
index 3af5f854dd..beec45cac9 100644
--- a/packages/api/src/defaultStyleOptions.js
+++ b/packages/api/src/defaultStyleOptions.ts
@@ -1,4 +1,5 @@
/* eslint no-magic-numbers: "off" */
+import StyleOptions from './StyleOptions';
function fontFamily(fonts) {
return fonts.map(font => `'${font}'`).join(', ');
@@ -8,33 +9,34 @@ const DEFAULT_ACCENT = '#0063B1';
const DEFAULT_SUBTLE = '#767676'; // With contrast 4.5:1 to white
const PADDING_REGULAR = 10;
-const DEFAULT_OPTIONS = {
- // Color and paddings
+const DEFAULT_OPTIONS: Required = {
+ // Basic styling
accent: DEFAULT_ACCENT,
backgroundColor: 'White',
- cardEmphasisBackgroundColor: '#F0F0F0',
+ subtle: DEFAULT_SUBTLE,
paddingRegular: PADDING_REGULAR,
paddingWide: PADDING_REGULAR * 2,
- subtle: DEFAULT_SUBTLE,
-
- // Word break
- messageActivityWordBreak: 'break-word', // 'normal' || 'break-all' || 'break-word' || 'keep-all'
-
- // Fonts
fontSizeSmall: '80%',
monospaceFont: fontFamily(['Consolas', 'Courier New', 'monospace']),
primaryFont: fontFamily(['Calibri', 'Helvetica Neue', 'Arial', 'sans-serif']),
+ // Root
+ rootHeight: '100%',
+ rootWidth: '100%',
+ rootZIndex: 0, // "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.
+
+ transitionDuration: '0s',
+
// Avatar
avatarBorderRadius: '50%',
avatarSize: 40,
- botAvatarBackgroundColor: undefined, // defaults to accent color
- botAvatarImage: undefined, // Or a string of URL. Can be a data URI or blob.
- botAvatarInitials: undefined, // Or a string. Empty strings means it has avatar but not initials inside.
- userAvatarBackgroundColor: undefined, // defaults to accent color
- userAvatarImage: undefined, // Or a string of URL. Can be a data URI or blob.
- userAvatarInitials: undefined, // Or a string. Empty strings means it has avatar but not initials inside.
- showAvatarInGroup: 'status', // Or 'sender' or true (on every activity).
+ botAvatarBackgroundColor: undefined,
+ botAvatarImage: undefined,
+ botAvatarInitials: undefined,
+ userAvatarBackgroundColor: undefined,
+ userAvatarImage: undefined,
+ userAvatarInitials: undefined,
+ showAvatarInGroup: 'status',
// Bubble
// TODO: Should we make a bubbleFromBot*
@@ -48,139 +50,126 @@ const DEFAULT_OPTIONS = {
bubbleFromUserBorderRadius: 2,
bubbleFromUserBorderStyle: 'solid',
bubbleFromUserBorderWidth: 1,
- bubbleFromUserNubOffset: 0, // Either a positive/negative number, or "bottom"
- bubbleFromUserNubSize: undefined, // Or a number. 0 means a sharp corner.
+ bubbleFromUserNubOffset: 0,
+ bubbleFromUserNubSize: undefined,
bubbleFromUserTextColor: 'Black',
bubbleImageHeight: 240,
- bubbleMaxWidth: 480, // screen width = 600px
+ bubbleMaxWidth: 480, // Based off screen width = 600px
bubbleMinHeight: 40,
- bubbleMinWidth: 250, // min screen width = 300px, Edge requires 372px (https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/13621468/)
- bubbleNubOffset: 0, // Either a positive/negative number, or "bottom"
- bubbleNubSize: undefined, // Or a number. 0 means a sharp corner.
+ bubbleMinWidth: 250, // min screen width = 300px; Microsoft Edge requires 372px (https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/13621468/)
+ bubbleNubOffset: 0,
+ bubbleNubSize: undefined,
bubbleTextColor: 'Black',
+ messageActivityWordBreak: 'break-word',
- // Markdown
- markdownRespectCRLF: true,
+ // Connectivity UI
+ connectivityIconPadding: PADDING_REGULAR * 1.2,
+ connectivityMarginLeftRight: PADDING_REGULAR * 1.4,
+ connectivityMarginTopBottom: PADDING_REGULAR * 0.8,
+ connectivityTextSize: '75%',
+ failedConnectivity: '#C50F1F',
+ slowConnectivity: '#EAA300',
+ notificationText: '#5E5E5E',
+ slowConnectionAfter: 15000,
- // Rich Cards
- richCardWrapTitle: false, // Applies to subtitles as well
+ // Emoji
+ emojiSet: true,
- // Root
- rootHeight: '100%',
- rootWidth: '100%',
- rootZIndex: 0, // "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.
+ // Live region - Accessibility
+ internalLiveRegionFadeAfter: 1000,
- // Scroll to end button
+ // Markdown
+ markdownExternalLinkIconImage:
+ 'url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIzIDMgMTggMTgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTcuMjUwMSA0LjUwMDE3SDEwLjc0OTVDMTEuMTYzNyA0LjUwMDE3IDExLjQ5OTUgNC44MzU5NiAxMS40OTk1IDUuMjUwMTdDMTEuNDk5NSA1LjYyOTg2IDExLjIxNzMgNS45NDM2NiAxMC44NTEzIDUuOTkzMzJMMTAuNzQ5NSA2LjAwMDE3SDcuMjQ5NzRDNi4wNzA3OSA1Ljk5OTYxIDUuMTAzNDkgNi45MDY1NiA1LjAwNzg2IDguMDYxMTJMNS4wMDAyOCA4LjIyMDAzTDUuMDAzMTIgMTYuNzUwN0M1LjAwMzQzIDE3Ljk0MTUgNS45Mjg4NSAxOC45MTYxIDcuMDk5NjYgMTguOTk0OUw3LjI1MzcxIDE5LjAwMDFMMTUuNzUxOCAxOC45ODg0QzE2Ljk0MTUgMTguOTg2OCAxNy45MTQ1IDE4LjA2MiAxNy45OTM1IDE2Ljg5MjNMMTcuOTk4NyAxNi43Mzg0VjEzLjIzMjFDMTcuOTk4NyAxMi44MTc5IDE4LjMzNDUgMTIuNDgyMSAxOC43NDg3IDEyLjQ4MjFDMTkuMTI4NCAxMi40ODIxIDE5LjQ0MjIgMTIuNzY0MyAxOS40OTE4IDEzLjEzMDNMMTkuNDk4NyAxMy4yMzIxVjE2LjczODRDMTkuNDk4NyAxOC43NDA3IDE3LjkyOTMgMjAuMzc2OSAxNS45NTI4IDIwLjQ4MjlMMTUuNzUzOCAyMC40ODg0TDcuMjU4MjcgMjAuNTAwMUw3LjA1NDk1IDIwLjQ5NDlDNS4xNDIzOSAyMC4zOTU0IDMuNjA4OTUgMTguODYyNyAzLjUwODM3IDE2Ljk1MDJMMy41MDMxMiAxNi43NTExTDMuNTAwODkgOC4yNTI3TDMuNTA1MjkgOC4wNTAyQzMuNjA1MzkgNi4xMzc0OSA1LjEzODY3IDQuNjA0NDkgNy4wNTA5NiA0LjUwNTI3TDcuMjUwMSA0LjUwMDE3SDEwLjc0OTVINy4yNTAxWk0xMy43NDgxIDMuMDAxNDZMMjAuMzAxOCAzLjAwMTk3TDIwLjQwMTQgMy4wMTU3NUwyMC41MDIyIDMuMDQzOTNMMjAuNTU5IDMuMDY4MDNDMjAuNjEyMiAzLjA5MTIyIDIwLjY2MzQgMy4xMjE2MyAyMC43MTExIDMuMTU4ODVMMjAuNzgwNCAzLjIyMTU2TDIwLjg2NDEgMy4zMjAxNEwyMC45MTgzIDMuNDEwMjVMMjAuOTU3IDMuNTAwNTdMMjAuOTc2MiAzLjU2NDc2TDIwLjk4OTggMy42Mjg2MkwyMC45OTkyIDMuNzIyODJMMjAuOTk5NyAxMC4yNTU0QzIwLjk5OTcgMTAuNjY5NiAyMC42NjM5IDExLjAwNTQgMjAuMjQ5NyAxMS4wMDU0QzE5Ljg3IDExLjAwNTQgMTkuNTU2MiAxMC43MjMyIDE5LjUwNjUgMTAuMzU3MUwxOS40OTk3IDEwLjI1NTRMMTkuNDk4OSA1LjU2MTQ3TDEyLjI3OTcgMTIuNzg0N0MxMi4wMTM0IDEzLjA1MSAxMS41OTY4IDEzLjA3NTMgMTEuMzAzMSAxMi44NTc1TDExLjIxOSAxMi43ODQ5QzEwLjk1MjcgMTIuNTE4NyAxMC45Mjg0IDEyLjEwMjEgMTEuMTQ2MiAxMS44MDg0TDExLjIxODggMTEuNzI0M0wxOC40MzY5IDQuNTAxNDZIMTMuNzQ4MUMxMy4zNjg0IDQuNTAxNDYgMTMuMDU0NiA0LjIxOTMxIDEzLjAwNSAzLjg1MzI0TDEyLjk5ODEgMy43NTE0NkMxMi45OTgxIDMuMzcxNzcgMTMuMjgwMyAzLjA1Nzk3IDEzLjY0NjQgMy4wMDgzMUwxMy43NDgxIDMuMDAxNDZaIiBmaWxsPSIjMjEyMTIxIiAvPjwvc3ZnPg==)',
+ markdownRespectCRLF: true,
+
+ // Scroll behavior
hideScrollToEndButton: false,
+ autoScrollSnapOnActivity: false,
+ autoScrollSnapOnActivityOffset: 0,
+ autoScrollSnapOnPage: false,
+ autoScrollSnapOnPageoffset: 0,
// Send box
hideSendBox: false,
hideUploadButton: false,
microphoneButtonColorOnDictate: '#F33',
sendBoxBackground: 'White',
- sendBoxButtonColor: undefined, // defaults to subtle
+ sendBoxButtonColor: undefined,
sendBoxButtonColorOnDisabled: '#CCC',
sendBoxButtonColorOnFocus: '#333',
sendBoxButtonColorOnHover: '#333',
- sendBoxDisabledTextColor: undefined, // defaults to subtle
+ sendBoxDisabledTextColor: undefined,
sendBoxHeight: 40,
sendBoxMaxHeight: 200,
sendBoxTextColor: 'Black',
// TODO: We should deprecate this because there isn't an easy way to make the width of the send box narrower than the transcript
- sendBoxBorderBottom: '',
- sendBoxBorderLeft: '',
- sendBoxBorderRight: '',
+ sendBoxBorderBottom: undefined,
+ sendBoxBorderLeft: undefined,
+ sendBoxBorderRight: undefined,
sendBoxBorderTop: 'solid 1px #E6E6E6',
- sendBoxPlaceholderColor: undefined, // defaults to subtle
+ sendBoxPlaceholderColor: undefined,
sendBoxTextWrap: false,
- sendBoxButtonAlignment: 'stretch', // "stretch", "top" or "bottom"
+ sendBoxButtonAlignment: 'stretch',
// Visually show spoken text
showSpokenText: false,
+ spinnerAnimationBackgroundImage: undefined,
+ spinnerAnimationHeight: 16,
+ spinnerAnimationWidth: 16,
+ spinnerAnimationPadding: 12,
+
// Suggested actions
suggestedActionBackground: 'White',
- suggestedActionBorder: undefined, // split into 3, null
- suggestedActionBorderColor: undefined, // defaults to accent
+ suggestedActionBorderColor: undefined,
suggestedActionBorderRadius: 0,
suggestedActionBorderStyle: 'solid',
suggestedActionBorderWidth: 2,
- suggestedActionDisabledBackground: undefined, // defaults to suggestedActionBackground
+ suggestedActionDisabledBackground: undefined,
suggestedActionDisabledBorderColor: '#E6E6E6',
suggestedActionDisabledBorderStyle: 'solid',
suggestedActionDisabledBorderWidth: 2,
- suggestedActionDisabledTextColor: undefined, // defaults to subtle
+ suggestedActionDisabledTextColor: undefined,
suggestedActionHeight: 40,
suggestedActionImageHeight: 20,
- suggestedActionLayout: 'carousel', // Either "carousel", "flow", or "stacked"
- suggestedActionTextColor: null,
+ suggestedActionLayout: 'carousel',
+ suggestedActionTextColor: undefined,
// Suggested actions carousel layout
- suggestedActionsCarouselFlipperCursor: null, // Cursor when mouse over on flipper
- suggestedActionsCarouselFlipperBoxWidth: 40, // Flipper bounding box size
- suggestedActionsCarouselFlipperSize: 20, // Flipper visible size
+ suggestedActionsCarouselFlipperCursor: undefined,
+ suggestedActionsCarouselFlipperBoxWidth: 40,
+ suggestedActionsCarouselFlipperSize: 20,
// Suggested actions flow layout
- suggestedActionsFlowMaxHeight: undefined, // Defaults to "auto".
+ suggestedActionsFlowMaxHeight: undefined,
// Suggested actions stacked layout
- suggestedActionsStackedHeight: undefined, // sets the container's max height. defaults to 'auto'
- suggestedActionsStackedOverflow: undefined, // defaults to 'auto',
- suggestedActionsStackedLayoutButtonMaxHeight: undefined, // defaults to 100% if suggestedActionsStackedLayoutButtonTextWrap is true
- suggestedActionsStackedLayoutButtonTextWrap: false, // if set to true, buttons with long text will wrap in STACKED mode ONLY
+ suggestedActionsStackedHeight: undefined,
+ suggestedActionsStackedOverflow: undefined,
+ suggestedActionsStackedLayoutButtonMaxHeight: undefined,
+ suggestedActionsStackedLayoutButtonTextWrap: false,
// Timestamp
groupTimestamp: true,
sendTimeout: 20000,
sendTimeoutForAttachments: 120000,
- timestampColor: undefined, // defaults to subtle
- timestampFormat: 'relative', // 'absolute'
+ timestampColor: undefined,
+ timestampFormat: 'relative',
- // Transcript overlay buttons (e.g. carousel and suggested action flippers, scroll to bottom, etc.)
+ // Transcript overlay buttons
newMessagesButtonFontSize: '85%',
transcriptOverlayButtonBackground: 'rgba(0, 0, 0, .6)',
+ transcriptOverlayButtonBackgroundOnDisabled: 'rgba(0, 0, 0, .6)',
transcriptOverlayButtonBackgroundOnFocus: 'rgba(0, 0, 0, .8)',
transcriptOverlayButtonBackgroundOnHover: 'rgba(0, 0, 0, .8)',
transcriptOverlayButtonColor: 'White',
- transcriptOverlayButtonColorOnFocus: undefined, // defaults to transcriptOverlayButtonColor
- transcriptOverlayButtonColorOnHover: undefined, // defaults to transcriptOverlayButtonColor
-
- // Video
- videoHeight: 270, // based on bubbleMaxWidth: 480 / 16 * 9 = 270
-
- // Connectivity UI
- connectivityIconPadding: PADDING_REGULAR * 1.2,
- connectivityMarginLeftRight: PADDING_REGULAR * 1.4,
- connectivityMarginTopBottom: PADDING_REGULAR * 0.8,
- connectivityTextSize: '75%',
- failedConnectivity: '#C50F1F',
- slowConnectivity: '#EAA300',
- notificationText: '#5E5E5E',
- slowConnectionAfter: 15000,
-
- typingAnimationBackgroundImage: null,
- typingAnimationDuration: 5000,
- typingAnimationHeight: 20,
- typingAnimationWidth: 64,
-
- spinnerAnimationBackgroundImage: null,
- spinnerAnimationHeight: 16,
- spinnerAnimationWidth: 16,
- spinnerAnimationPadding: 12,
-
- // TODO: [P0] #3322 This is only supported on HTML.
- enableUploadThumbnail: true,
- uploadThumbnailContentType: 'image/jpeg',
- uploadThumbnailHeight: 360,
- uploadThumbnailQuality: 0.6,
- uploadThumbnailWidth: 720,
-
- // deprecated; will be removed on or after 2021-02-01
- spinnerAnimationPaddingRight: undefined,
+ transcriptOverlayButtonColorOnDisabled: 'White',
+ transcriptOverlayButtonColorOnFocus: undefined,
+ transcriptOverlayButtonColorOnHover: undefined,
// Toast UI
- // New debounce timeout value only affects new notifications.
notificationDebounceTimeout: 400,
hideToaster: false,
@@ -201,17 +190,36 @@ const DEFAULT_OPTIONS = {
toastWarnBackgroundColor: '#FFF4CE',
toastWarnColor: '#3B3A39',
- // Emoji
- emojiSet: true, // true || false || { ':)' : 'đ'}
+ // Transcript
+ transcriptTerminatorBackgroundColor: '#595959',
+ transcriptTerminatorBorderRadius: 5,
+ transcriptTerminatorColor: 'White',
+ transcriptTerminatorFontSize: 12,
- // Auto-scroll behavior
- autoScrollSnapOnActivity: false, // true will pause scroll after 1 activity is received. Specifying a number will pause after X number of activities
- autoScrollSnapOnActivityOffset: 0, // Specify number of pixels to overscroll or underscroll after pause
- autoScrollSnapOnPage: false, // true will pause scroll after activities filled the page. Specifying a number (0 to 1) will pause after % of page is filled
- autoScrollSnapOnPageoffset: 0, // Specify number of pixels to overscroll or underscroll after pause
+ transcriptActivityVisualKeyboardIndicatorColor: DEFAULT_SUBTLE,
+ transcriptActivityVisualKeyboardIndicatorStyle: 'dashed',
+ transcriptActivityVisualKeyboardIndicatorWidth: 1,
- markdownExternalLinkIconImage:
- 'url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIzIDMgMTggMTgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTcuMjUwMSA0LjUwMDE3SDEwLjc0OTVDMTEuMTYzNyA0LjUwMDE3IDExLjQ5OTUgNC44MzU5NiAxMS40OTk1IDUuMjUwMTdDMTEuNDk5NSA1LjYyOTg2IDExLjIxNzMgNS45NDM2NiAxMC44NTEzIDUuOTkzMzJMMTAuNzQ5NSA2LjAwMDE3SDcuMjQ5NzRDNi4wNzA3OSA1Ljk5OTYxIDUuMTAzNDkgNi45MDY1NiA1LjAwNzg2IDguMDYxMTJMNS4wMDAyOCA4LjIyMDAzTDUuMDAzMTIgMTYuNzUwN0M1LjAwMzQzIDE3Ljk0MTUgNS45Mjg4NSAxOC45MTYxIDcuMDk5NjYgMTguOTk0OUw3LjI1MzcxIDE5LjAwMDFMMTUuNzUxOCAxOC45ODg0QzE2Ljk0MTUgMTguOTg2OCAxNy45MTQ1IDE4LjA2MiAxNy45OTM1IDE2Ljg5MjNMMTcuOTk4NyAxNi43Mzg0VjEzLjIzMjFDMTcuOTk4NyAxMi44MTc5IDE4LjMzNDUgMTIuNDgyMSAxOC43NDg3IDEyLjQ4MjFDMTkuMTI4NCAxMi40ODIxIDE5LjQ0MjIgMTIuNzY0MyAxOS40OTE4IDEzLjEzMDNMMTkuNDk4NyAxMy4yMzIxVjE2LjczODRDMTkuNDk4NyAxOC43NDA3IDE3LjkyOTMgMjAuMzc2OSAxNS45NTI4IDIwLjQ4MjlMMTUuNzUzOCAyMC40ODg0TDcuMjU4MjcgMjAuNTAwMUw3LjA1NDk1IDIwLjQ5NDlDNS4xNDIzOSAyMC4zOTU0IDMuNjA4OTUgMTguODYyNyAzLjUwODM3IDE2Ljk1MDJMMy41MDMxMiAxNi43NTExTDMuNTAwODkgOC4yNTI3TDMuNTA1MjkgOC4wNTAyQzMuNjA1MzkgNi4xMzc0OSA1LjEzODY3IDQuNjA0NDkgNy4wNTA5NiA0LjUwNTI3TDcuMjUwMSA0LjUwMDE3SDEwLjc0OTVINy4yNTAxWk0xMy43NDgxIDMuMDAxNDZMMjAuMzAxOCAzLjAwMTk3TDIwLjQwMTQgMy4wMTU3NUwyMC41MDIyIDMuMDQzOTNMMjAuNTU5IDMuMDY4MDNDMjAuNjEyMiAzLjA5MTIyIDIwLjY2MzQgMy4xMjE2MyAyMC43MTExIDMuMTU4ODVMMjAuNzgwNCAzLjIyMTU2TDIwLjg2NDEgMy4zMjAxNEwyMC45MTgzIDMuNDEwMjVMMjAuOTU3IDMuNTAwNTdMMjAuOTc2MiAzLjU2NDc2TDIwLjk4OTggMy42Mjg2MkwyMC45OTkyIDMuNzIyODJMMjAuOTk5NyAxMC4yNTU0QzIwLjk5OTcgMTAuNjY5NiAyMC42NjM5IDExLjAwNTQgMjAuMjQ5NyAxMS4wMDU0QzE5Ljg3IDExLjAwNTQgMTkuNTU2MiAxMC43MjMyIDE5LjUwNjUgMTAuMzU3MUwxOS40OTk3IDEwLjI1NTRMMTkuNDk4OSA1LjU2MTQ3TDEyLjI3OTcgMTIuNzg0N0MxMi4wMTM0IDEzLjA1MSAxMS41OTY4IDEzLjA3NTMgMTEuMzAzMSAxMi44NTc1TDExLjIxOSAxMi43ODQ5QzEwLjk1MjcgMTIuNTE4NyAxMC45Mjg0IDEyLjEwMjEgMTEuMTQ2MiAxMS44MDg0TDExLjIxODggMTEuNzI0M0wxOC40MzY5IDQuNTAxNDZIMTMuNzQ4MUMxMy4zNjg0IDQuNTAxNDYgMTMuMDU0NiA0LjIxOTMxIDEzLjAwNSAzLjg1MzI0TDEyLjk5ODEgMy43NTE0NkMxMi45OTgxIDMuMzcxNzcgMTMuMjgwMyAzLjA1Nzk3IDEzLjY0NjQgMy4wMDgzMUwxMy43NDgxIDMuMDAxNDZaIiBmaWxsPSIjMjEyMTIxIiAvPjwvc3ZnPg==)'
+ transcriptVisualKeyboardIndicatorColor: 'Black',
+ transcriptVisualKeyboardIndicatorStyle: 'solid',
+ transcriptVisualKeyboardIndicatorWidth: 2,
+
+ // Typing animation
+ typingAnimationBackgroundImage: undefined,
+ typingAnimationDuration: 5000,
+ typingAnimationHeight: 20,
+ typingAnimationWidth: 64,
+
+ // Upload thumbnail
+ // TODO: [P0] #3322 This is only supported in HTML.
+ enableUploadThumbnail: true,
+ uploadThumbnailContentType: 'image/jpeg',
+ uploadThumbnailHeight: 360,
+ uploadThumbnailQuality: 0.6,
+ uploadThumbnailWidth: 720,
+
+ // Video
+ videoHeight: 270 // based on bubbleMaxWidth: 480 / 16 * 9 = 270
};
export default DEFAULT_OPTIONS;
diff --git a/packages/api/src/hooks/Composer.js b/packages/api/src/hooks/Composer.tsx
similarity index 91%
rename from packages/api/src/hooks/Composer.js
rename to packages/api/src/hooks/Composer.tsx
index 12e78f382c..10610141a5 100644
--- a/packages/api/src/hooks/Composer.js
+++ b/packages/api/src/hooks/Composer.tsx
@@ -1,6 +1,6 @@
import { Provider } from 'react-redux';
import PropTypes from 'prop-types';
-import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+import React, { FC, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import updateIn from 'simple-update-in';
import createCustomEvent from '../utils/createCustomEvent';
@@ -8,7 +8,9 @@ import ErrorBoundary from './utils/ErrorBoundary';
import getAllLocalizedStrings from '../localization/getAllLocalizedStrings';
import isObject from '../utils/isObject';
import normalizeLanguage from '../utils/normalizeLanguage';
+// @ts-ignore
import PrecompiledGlobalize from '../external/PrecompiledGlobalize';
+import StyleOptions from '../StyleOptions';
import {
clearSuggestedActions,
@@ -45,14 +47,15 @@ import mapMap from '../utils/mapMap';
import observableToPromise from './utils/observableToPromise';
import Tracker from './internal/Tracker';
import WebChatReduxContext, { useDispatch } from './internal/WebChatReduxContext';
-import WebChatAPIContext from './internal/WebChatAPIContext';
+import { default as WebChatAPIContext } from './internal/WebChatAPIContext';
import applyMiddleware, {
forLegacyRenderer as applyMiddlewareForLegacyRenderer,
forRenderer as applyMiddlewareForRenderer
} from './middleware/applyMiddleware';
-import patchStyleOptions from '../patchStyleOptions';
+import normalizeStyleOptions from '../normalizeStyleOptions';
+import patchStyleOptionsFromDeprecatedProps from '../patchStyleOptionsFromDeprecatedProps';
import singleToArray from './utils/singleToArray';
// List of Redux actions factory we are hoisting as Web Chat functions
@@ -87,7 +90,7 @@ function createCardActionContext({ cardActionMiddleware, directLine, dispatch })
)({ dispatch });
return {
- onCardAction: (cardAction, { target } = {}) =>
+ onCardAction: (cardAction, { target }: { target?: any } = {}) =>
runMiddleware({
cardAction,
getSignInUrl:
@@ -148,7 +151,44 @@ function mergeStringsOverrides(localizedStrings, language, overrideLocalizedStri
return { ...localizedStrings, ...overrideLocalizedStrings };
}
-const Composer = ({
+type ComposerProps = {
+ activityMiddleware: any;
+ activityRenderer: any;
+ activityStatusMiddleware: any;
+ activityStatusRenderer: any;
+ attachmentForScreenReaderMiddleware: any;
+ attachmentMiddleware: any;
+ attachmentRenderer: any;
+ avatarMiddleware: any;
+ avatarRenderer: any;
+ cardActionMiddleware: any;
+ children: ReactNode;
+ dir: string;
+ directLine: any;
+ disabled: boolean;
+ downscaleImageToDataURL: any;
+ grammars: any;
+ groupActivitiesMiddleware: any;
+ groupTimestamp: boolean | number;
+ internalErrorBoxClass: any;
+ internalRenderErrorBox: any;
+ locale: string;
+ onTelemetry: any;
+ overrideLocalizedStrings: any;
+ renderMarkdown: any;
+ selectVoice: any;
+ sendTimeout: number;
+ sendTypingIndicator: any;
+ styleOptions: StyleOptions;
+ toastMiddleware: any;
+ toastRenderer: any;
+ typingIndicatorMiddleware: any;
+ typingIndicatorRenderer: any;
+ userID: string;
+ username: string;
+};
+
+const Composer: FC = ({
activityMiddleware,
activityRenderer,
activityStatusMiddleware,
@@ -188,11 +228,10 @@ const Composer = ({
const patchedDir = useMemo(() => (dir === 'ltr' || dir === 'rtl' ? dir : 'auto'), [dir]);
const patchedGrammars = useMemo(() => grammars || [], [grammars]);
- const patchedStyleOptions = useMemo(() => patchStyleOptions(styleOptions, { groupTimestamp, sendTimeout }), [
- groupTimestamp,
- sendTimeout,
- styleOptions
- ]);
+ const patchedStyleOptions = useMemo(
+ () => normalizeStyleOptions(patchStyleOptionsFromDeprecatedProps(styleOptions, { groupTimestamp, sendTimeout })),
+ [groupTimestamp, sendTimeout, styleOptions]
+ );
useEffect(() => {
dispatch(setLanguage(locale));
@@ -503,7 +542,12 @@ const Composer = ({
};
// We will create a Redux store if it was not passed in
-const ComposeWithStore = ({ internalRenderErrorBox, onTelemetry, store, ...props }) => {
+const ComposeWithStore: FC = ({
+ internalRenderErrorBox,
+ onTelemetry,
+ store,
+ ...props
+}) => {
const [error, setError] = useState();
const handleError = useCallback(
diff --git a/packages/api/src/hooks/internal/Tracker.js b/packages/api/src/hooks/internal/Tracker.ts
similarity index 61%
rename from packages/api/src/hooks/internal/Tracker.js
rename to packages/api/src/hooks/internal/Tracker.ts
index 3dffdab20f..5c5363edf7 100644
--- a/packages/api/src/hooks/internal/Tracker.js
+++ b/packages/api/src/hooks/internal/Tracker.ts
@@ -1,9 +1,9 @@
import useTracker from './useTracker';
-const Tracker = () => {
+const Tracker: React.FC<{}> = () => {
useTracker();
- return false;
+ return null;
};
export default Tracker;
diff --git a/packages/api/src/hooks/internal/WebChatAPIContext.js b/packages/api/src/hooks/internal/WebChatAPIContext.ts
similarity index 78%
rename from packages/api/src/hooks/internal/WebChatAPIContext.js
rename to packages/api/src/hooks/internal/WebChatAPIContext.ts
index c25d3d4c41..bb6407ab72 100644
--- a/packages/api/src/hooks/internal/WebChatAPIContext.js
+++ b/packages/api/src/hooks/internal/WebChatAPIContext.ts
@@ -1,6 +1,6 @@
import { createContext } from 'react';
-const context = createContext({
+const context = createContext({
sendFocusRef: null
});
diff --git a/packages/api/src/index.js b/packages/api/src/index.js
new file mode 100644
index 0000000000..9d1778fa47
--- /dev/null
+++ b/packages/api/src/index.js
@@ -0,0 +1,10 @@
+// IMPORTANT: To export anything from this file, add it to index.tsx, which is the .d.ts for this file.
+
+import * as hooks from './hooks';
+import Composer from './hooks/Composer';
+import concatMiddleware from './hooks/middleware/concatMiddleware';
+import defaultStyleOptions from './defaultStyleOptions';
+import Localize, { localize } from './localization/Localize';
+import normalizeStyleOptions from './normalizeStyleOptions';
+
+export { Composer, concatMiddleware, defaultStyleOptions, hooks, Localize, localize, normalizeStyleOptions };
diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts
deleted file mode 100644
index 501e2d5659..0000000000
--- a/packages/api/src/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import * as hooks from './hooks';
-import Composer from './hooks/Composer';
-import concatMiddleware from './hooks/middleware/concatMiddleware';
-import Localize, { localize } from './localization/Localize';
-
-export { Composer, concatMiddleware, hooks, Localize, localize };
diff --git a/packages/api/src/index.tsx b/packages/api/src/index.tsx
new file mode 100644
index 0000000000..7d9393c392
--- /dev/null
+++ b/packages/api/src/index.tsx
@@ -0,0 +1,10 @@
+import StyleOptions, { StrictStyleOptions } from './StyleOptions';
+
+declare const defaultStyleOptions: Required;
+
+// TODO: [P2] ESLint of DLSpeech SDK should ignore this file since its from API.
+// eslint-disable-next-line no-unused-vars
+declare function normalizeStyleOptions(styleOptions: StyleOptions): StrictStyleOptions;
+
+export type { StrictStyleOptions, StyleOptions };
+export { defaultStyleOptions, normalizeStyleOptions };
diff --git a/packages/api/src/normalizeStyleOptions.ts b/packages/api/src/normalizeStyleOptions.ts
new file mode 100644
index 0000000000..3ef3e81262
--- /dev/null
+++ b/packages/api/src/normalizeStyleOptions.ts
@@ -0,0 +1,76 @@
+import defaultStyleOptions from './defaultStyleOptions';
+import StyleOptions, { StrictStyleOptions } from './StyleOptions';
+
+// TODO: [P4] We should add a notice for people who want to use "styleSet" instead of "styleOptions".
+// "styleSet" is actually CSS stylesheet and it is based on the DOM tree.
+// DOM tree may change from time to time, thus, maintaining "styleSet" becomes a constant effort.
+
+// eslint-disable-next-line complexity
+export default function normalizeStyleOptions(options: StyleOptions = {}): StrictStyleOptions {
+ const filledOptions: Required = { ...defaultStyleOptions, ...options };
+
+ // Keep this list flat (no nested style) and serializable (no functions)
+ const { bubbleFromUserNubOffset, bubbleNubOffset, emojiSet } = filledOptions;
+
+ let normalizedBubbleFromUserNubOffset: number;
+ let normalizedBubbleNubOffset: number;
+ let normalizedEmojiSet: false | Record;
+
+ if (bubbleFromUserNubOffset === 'top') {
+ normalizedBubbleFromUserNubOffset = 0;
+ } else if (typeof bubbleFromUserNubOffset !== 'number') {
+ normalizedBubbleFromUserNubOffset = -0;
+ } else {
+ normalizedBubbleFromUserNubOffset = bubbleFromUserNubOffset;
+ }
+
+ if (bubbleNubOffset === 'top') {
+ normalizedBubbleNubOffset = 0;
+ } else if (typeof bubbleNubOffset !== 'number') {
+ normalizedBubbleNubOffset = -0;
+ } else {
+ normalizedBubbleNubOffset = bubbleNubOffset;
+ }
+
+ if (emojiSet === true) {
+ normalizedEmojiSet = {
+ ':)': 'đ',
+ ':-)': 'đ',
+ '(:': 'đ',
+ '(-:': 'đ',
+ ':-|': 'đ',
+ ':|': 'đ',
+ ':-(': 'âšī¸',
+ ':(': 'âšī¸',
+ ':-D': 'đ',
+ ':D': 'đ',
+ ':-p': 'đ',
+ ':p': 'đ',
+ ':-P': 'đ',
+ ':P': 'đ',
+ ':-o': 'đ˛',
+ ':o': 'đ˛',
+ ':O': 'đ˛',
+ ':-O': 'đ˛',
+ ':-0': 'đ˛',
+ ':0': 'đ˛',
+ ';-)': 'đ',
+ ';)': 'đ',
+ '<3': 'â¤ī¸',
+ '3': 'đ',
+ '<\\3': 'đ'
+ };
+ } else if (Object.prototype.toString.call(emojiSet) !== '[object Object]') {
+ console.warn('botframework-webchat: emojiSet must be a boolean or an object with emoticon: emojiValues');
+ normalizedEmojiSet = false;
+ } else {
+ normalizedEmojiSet = emojiSet;
+ }
+
+ return {
+ ...filledOptions,
+ bubbleFromUserNubOffset: normalizedBubbleFromUserNubOffset,
+ bubbleNubOffset: normalizedBubbleNubOffset,
+ emojiSet: normalizedEmojiSet
+ };
+}
diff --git a/packages/api/src/patchStyleOptions.js b/packages/api/src/patchStyleOptions.js
deleted file mode 100644
index f7026c2bb2..0000000000
--- a/packages/api/src/patchStyleOptions.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import defaultStyleOptions from './defaultStyleOptions';
-
-// TODO: [P4] We should add a notice for people who want to use "styleSet" instead of "styleOptions".
-// "styleSet" is actually CSS stylesheet and it is based on the DOM tree.
-// DOM tree may change from time to time, thus, maintaining "styleSet" becomes a constant effort.
-
-// eslint-disable-next-line complexity
-export default function patchStyleOptions(
- options,
- { groupTimestamp: groupTimestampFromProps, sendTimeout: sendTimeoutFromProps }
-) {
- const patchedOptions = { ...defaultStyleOptions, ...options };
-
- // Keep this list flat (no nested style) and serializable (no functions)
-
- // TODO: [P4] Deprecate this code after bump to v5
- const { bubbleFromUserNubOffset, bubbleNubOffset, emojiSet } = patchedOptions;
-
- if (bubbleFromUserNubOffset === 'top') {
- patchedOptions.bubbleFromUserNubOffset = 0;
- } else if (typeof bubbleFromUserNubOffset !== 'number') {
- patchedOptions.bubbleFromUserNubOffset = -0;
- }
-
- if (bubbleNubOffset === 'top') {
- patchedOptions.bubbleNubOffset = 0;
- } else if (typeof bubbleNubOffset !== 'number') {
- patchedOptions.bubbleNubOffset = -0;
- }
-
- if (emojiSet === true) {
- patchedOptions.emojiSet = {
- ':)': 'đ',
- ':-)': 'đ',
- '(:': 'đ',
- '(-:': 'đ',
- ':-|': 'đ',
- ':|': 'đ',
- ':-(': 'âšī¸',
- ':(': 'âšī¸',
- ':-D': 'đ',
- ':D': 'đ',
- ':-p': 'đ',
- ':p': 'đ',
- ':-P': 'đ',
- ':P': 'đ',
- ':-o': 'đ˛',
- ':o': 'đ˛',
- ':O': 'đ˛',
- ':-O': 'đ˛',
- ':-0': 'đ˛',
- ':0': 'đ˛',
- ';-)': 'đ',
- ';)': 'đ',
- '<3': 'â¤ī¸',
- '3': 'đ',
- '<\\3': 'đ'
- };
- } else if (Object.prototype.toString.call(patchedOptions.emojiSet) !== '[object Object]') {
- console.warn('botframework-webchat: emojiSet must be a boolean or an object with emoticon: emojiValues');
- patchedOptions.emojiSet = false;
- }
-
- if (typeof groupTimestampFromProps !== 'undefined' && typeof options.groupTimestamp === 'undefined') {
- console.warn(
- 'Web Chat: "groupTimestamp" has been moved to "styleOptions". This deprecation migration will be removed on or after January 1 2022.'
- );
-
- patchedOptions.groupTimestamp = groupTimestampFromProps;
- }
-
- if (typeof sendTimeoutFromProps !== 'undefined' && typeof options.sendTimeout === 'undefined') {
- console.warn(
- 'Web Chat: "sendTimeout" has been moved to "styleOptions". This deprecation migration will be removed on or after January 1 2022.'
- );
-
- patchedOptions.sendTimeout = sendTimeoutFromProps;
- }
-
- if (patchedOptions.slowConnectionAfter < 0) {
- console.warn('Web Chat: "slowConnectionAfter" cannot be negative, will set to 0.');
-
- patchedOptions.slowConnectionAfter = 0;
- }
-
- return patchedOptions;
-}
diff --git a/packages/api/src/patchStyleOptionsFromDeprecatedProps.js b/packages/api/src/patchStyleOptionsFromDeprecatedProps.js
new file mode 100644
index 0000000000..b95204a36e
--- /dev/null
+++ b/packages/api/src/patchStyleOptionsFromDeprecatedProps.js
@@ -0,0 +1,35 @@
+import updateIn from 'simple-update-in';
+
+// TODO: [P4] We should add a notice for people who want to use "styleSet" instead of "styleOptions".
+// "styleSet" is actually CSS stylesheet and it is based on the DOM tree.
+// DOM tree may change from time to time, thus, maintaining "styleSet" becomes a constant effort.
+
+// eslint-disable-next-line complexity
+export default function patchStyleOptionsFromDeprecatedProps(
+ styleOptions,
+ { groupTimestamp: groupTimestampFromProps, sendTimeout: sendTimeoutFromProps }
+) {
+ if (typeof groupTimestampFromProps !== 'undefined' && typeof styleOptions.groupTimestamp === 'undefined') {
+ console.warn(
+ 'Web Chat: "groupTimestamp" has been moved to "styleOptions". This deprecation migration will be removed on or after January 1 2022.'
+ );
+
+ styleOptions = updateIn(styleOptions, ['groupTimestamp'], () => groupTimestampFromProps);
+ }
+
+ if (typeof sendTimeoutFromProps !== 'undefined' && typeof styleOptions.sendTimeout === 'undefined') {
+ console.warn(
+ 'Web Chat: "sendTimeout" has been moved to "styleOptions". This deprecation migration will be removed on or after January 1 2022.'
+ );
+
+ styleOptions = updateIn(styleOptions, ['sendTimeout'], () => sendTimeoutFromProps);
+ }
+
+ if (styleOptions.slowConnectionAfter < 0) {
+ console.warn('Web Chat: "slowConnectionAfter" cannot be negative, will set to 0.');
+
+ styleOptions = updateIn(styleOptions, ['slowConnectionAfter'], () => 0);
+ }
+
+ return styleOptions;
+}
diff --git a/packages/api/src/tsconfig.json b/packages/api/src/tsconfig.json
index ca32a35acf..35417e5ca6 100644
--- a/packages/api/src/tsconfig.json
+++ b/packages/api/src/tsconfig.json
@@ -3,11 +3,13 @@
"allowSyntheticDefaultImports": true,
"declaration": true,
"declarationDir": "../lib",
+ "declarationMap": true,
"emitDeclarationOnly": true,
- "isolatedModules": true,
"jsx": "react",
"preserveWatchOutput": true,
"pretty": true,
- "skipLibCheck": true
- }
+ "skipLibCheck": true,
+ "sourceMap": true
+ },
+ "files": ["index.tsx"]
}
diff --git a/packages/bundle/babel.config.json b/packages/bundle/babel.config.json
index 35e0d17fac..96a91c73ef 100644
--- a/packages/bundle/babel.config.json
+++ b/packages/bundle/babel.config.json
@@ -4,6 +4,7 @@
"plugins": ["babel-plugin-istanbul"]
}
},
+ "ignore": ["src/index.tsx", "src/index-es5.tsx", "src/index-minimal.tsx"],
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-object-rest-spread",
diff --git a/packages/bundle/package-lock.json b/packages/bundle/package-lock.json
index 2768f0ea97..585e3b5a3e 100644
--- a/packages/bundle/package-lock.json
+++ b/packages/bundle/package-lock.json
@@ -2981,13 +2981,13 @@
}
},
"@typescript-eslint/eslint-plugin": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.18.0.tgz",
- "integrity": "sha512-Lzkc/2+7EoH7+NjIWLS2lVuKKqbEmJhtXe3rmfA8cyiKnZm3IfLf51irnBcmow8Q/AptVV0XBZmBJKuUJTe6cQ==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.19.0.tgz",
+ "integrity": "sha512-CRQNQ0mC2Pa7VLwKFbrGVTArfdVDdefS+gTw0oC98vSI98IX5A8EVH4BzJ2FOB0YlCmm8Im36Elad/Jgtvveaw==",
"dev": true,
"requires": {
- "@typescript-eslint/experimental-utils": "4.18.0",
- "@typescript-eslint/scope-manager": "4.18.0",
+ "@typescript-eslint/experimental-utils": "4.19.0",
+ "@typescript-eslint/scope-manager": "4.19.0",
"debug": "^4.1.1",
"functional-red-black-tree": "^1.0.1",
"lodash": "^4.17.15",
@@ -2997,28 +2997,28 @@
},
"dependencies": {
"@typescript-eslint/scope-manager": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.18.0.tgz",
- "integrity": "sha512-olX4yN6rvHR2eyFOcb6E4vmhDPsfdMyfQ3qR+oQNkAv8emKKlfxTWUXU5Mqxs2Fwe3Pf1BoPvrwZtwngxDzYzQ==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.19.0.tgz",
+ "integrity": "sha512-GGy4Ba/hLXwJXygkXqMzduqOMc+Na6LrJTZXJWVhRrSuZeXmu8TAnniQVKgj8uTRKe4igO2ysYzH+Np879G75g==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "4.18.0",
- "@typescript-eslint/visitor-keys": "4.18.0"
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/visitor-keys": "4.19.0"
}
},
"@typescript-eslint/types": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.18.0.tgz",
- "integrity": "sha512-/BRociARpj5E+9yQ7cwCF/SNOWwXJ3qhjurMuK2hIFUbr9vTuDeu476Zpu+ptxY2kSxUHDGLLKy+qGq2sOg37A==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.19.0.tgz",
+ "integrity": "sha512-A4iAlexVvd4IBsSTNxdvdepW0D4uR/fwxDrKUa+iEY9UWvGREu2ZyB8ylTENM1SH8F7bVC9ac9+si3LWNxcBuA==",
"dev": true
},
"@typescript-eslint/visitor-keys": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.18.0.tgz",
- "integrity": "sha512-Q9t90JCvfYaN0OfFUgaLqByOfz8yPeTAdotn/XYNm5q9eHax90gzdb+RJ6E9T5s97Kv/UHWKERTmqA0jTKAEHw==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.19.0.tgz",
+ "integrity": "sha512-aGPS6kz//j7XLSlgpzU2SeTqHPsmRYxFztj2vPuMMFJXZudpRSehE3WCV+BaxwZFvfAqMoSd86TEuM0PQ59E/A==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "4.18.0",
+ "@typescript-eslint/types": "4.19.0",
"eslint-visitor-keys": "^2.0.0"
}
},
@@ -3032,9 +3032,9 @@
}
},
"semver": {
- "version": "7.3.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
- "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -3049,43 +3049,43 @@
}
},
"@typescript-eslint/experimental-utils": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.18.0.tgz",
- "integrity": "sha512-92h723Kblt9JcT2RRY3QS2xefFKar4ZQFVs3GityOKWQYgtajxt/tuXIzL7sVCUlM1hgreiV5gkGYyBpdOwO6A==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.19.0.tgz",
+ "integrity": "sha512-9/23F1nnyzbHKuoTqFN1iXwN3bvOm/PRIXSBR3qFAYotK/0LveEOHr5JT1WZSzcD6BESl8kPOG3OoDRKO84bHA==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
- "@typescript-eslint/scope-manager": "4.18.0",
- "@typescript-eslint/types": "4.18.0",
- "@typescript-eslint/typescript-estree": "4.18.0",
+ "@typescript-eslint/scope-manager": "4.19.0",
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/typescript-estree": "4.19.0",
"eslint-scope": "^5.0.0",
"eslint-utils": "^2.0.0"
},
"dependencies": {
"@typescript-eslint/scope-manager": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.18.0.tgz",
- "integrity": "sha512-olX4yN6rvHR2eyFOcb6E4vmhDPsfdMyfQ3qR+oQNkAv8emKKlfxTWUXU5Mqxs2Fwe3Pf1BoPvrwZtwngxDzYzQ==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.19.0.tgz",
+ "integrity": "sha512-GGy4Ba/hLXwJXygkXqMzduqOMc+Na6LrJTZXJWVhRrSuZeXmu8TAnniQVKgj8uTRKe4igO2ysYzH+Np879G75g==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "4.18.0",
- "@typescript-eslint/visitor-keys": "4.18.0"
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/visitor-keys": "4.19.0"
}
},
"@typescript-eslint/types": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.18.0.tgz",
- "integrity": "sha512-/BRociARpj5E+9yQ7cwCF/SNOWwXJ3qhjurMuK2hIFUbr9vTuDeu476Zpu+ptxY2kSxUHDGLLKy+qGq2sOg37A==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.19.0.tgz",
+ "integrity": "sha512-A4iAlexVvd4IBsSTNxdvdepW0D4uR/fwxDrKUa+iEY9UWvGREu2ZyB8ylTENM1SH8F7bVC9ac9+si3LWNxcBuA==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.18.0.tgz",
- "integrity": "sha512-wt4xvF6vvJI7epz+rEqxmoNQ4ZADArGQO9gDU+cM0U5fdVv7N+IAuVoVAoZSOZxzGHBfvE3XQMLdy+scsqFfeg==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.19.0.tgz",
+ "integrity": "sha512-3xqArJ/A62smaQYRv2ZFyTA+XxGGWmlDYrsfZG68zJeNbeqRScnhf81rUVa6QG4UgzHnXw5VnMT5cg75dQGDkA==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "4.18.0",
- "@typescript-eslint/visitor-keys": "4.18.0",
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/visitor-keys": "4.19.0",
"debug": "^4.1.1",
"globby": "^11.0.1",
"is-glob": "^4.0.1",
@@ -3094,12 +3094,12 @@
}
},
"@typescript-eslint/visitor-keys": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.18.0.tgz",
- "integrity": "sha512-Q9t90JCvfYaN0OfFUgaLqByOfz8yPeTAdotn/XYNm5q9eHax90gzdb+RJ6E9T5s97Kv/UHWKERTmqA0jTKAEHw==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.19.0.tgz",
+ "integrity": "sha512-aGPS6kz//j7XLSlgpzU2SeTqHPsmRYxFztj2vPuMMFJXZudpRSehE3WCV+BaxwZFvfAqMoSd86TEuM0PQ59E/A==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "4.18.0",
+ "@typescript-eslint/types": "4.19.0",
"eslint-visitor-keys": "^2.0.0"
}
},
@@ -3123,9 +3123,9 @@
}
},
"semver": {
- "version": "7.3.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
- "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -3140,41 +3140,41 @@
}
},
"@typescript-eslint/parser": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.18.0.tgz",
- "integrity": "sha512-W3z5S0ZbecwX3PhJEAnq4mnjK5JJXvXUDBYIYGoweCyWyuvAKfGHvzmpUzgB5L4cRBb+cTu9U/ro66dx7dIimA==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.19.0.tgz",
+ "integrity": "sha512-/uabZjo2ZZhm66rdAu21HA8nQebl3lAIDcybUoOxoI7VbZBYavLIwtOOmykKCJy+Xq6Vw6ugkiwn8Js7D6wieA==",
"dev": true,
"requires": {
- "@typescript-eslint/scope-manager": "4.18.0",
- "@typescript-eslint/types": "4.18.0",
- "@typescript-eslint/typescript-estree": "4.18.0",
+ "@typescript-eslint/scope-manager": "4.19.0",
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/typescript-estree": "4.19.0",
"debug": "^4.1.1"
}
},
"@typescript-eslint/scope-manager": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.18.0.tgz",
- "integrity": "sha512-olX4yN6rvHR2eyFOcb6E4vmhDPsfdMyfQ3qR+oQNkAv8emKKlfxTWUXU5Mqxs2Fwe3Pf1BoPvrwZtwngxDzYzQ==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.19.0.tgz",
+ "integrity": "sha512-GGy4Ba/hLXwJXygkXqMzduqOMc+Na6LrJTZXJWVhRrSuZeXmu8TAnniQVKgj8uTRKe4igO2ysYzH+Np879G75g==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "4.18.0",
- "@typescript-eslint/visitor-keys": "4.18.0"
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/visitor-keys": "4.19.0"
}
},
"@typescript-eslint/types": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.18.0.tgz",
- "integrity": "sha512-/BRociARpj5E+9yQ7cwCF/SNOWwXJ3qhjurMuK2hIFUbr9vTuDeu476Zpu+ptxY2kSxUHDGLLKy+qGq2sOg37A==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.19.0.tgz",
+ "integrity": "sha512-A4iAlexVvd4IBsSTNxdvdepW0D4uR/fwxDrKUa+iEY9UWvGREu2ZyB8ylTENM1SH8F7bVC9ac9+si3LWNxcBuA==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.18.0.tgz",
- "integrity": "sha512-wt4xvF6vvJI7epz+rEqxmoNQ4ZADArGQO9gDU+cM0U5fdVv7N+IAuVoVAoZSOZxzGHBfvE3XQMLdy+scsqFfeg==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.19.0.tgz",
+ "integrity": "sha512-3xqArJ/A62smaQYRv2ZFyTA+XxGGWmlDYrsfZG68zJeNbeqRScnhf81rUVa6QG4UgzHnXw5VnMT5cg75dQGDkA==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "4.18.0",
- "@typescript-eslint/visitor-keys": "4.18.0",
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/visitor-keys": "4.19.0",
"debug": "^4.1.1",
"globby": "^11.0.1",
"is-glob": "^4.0.1",
@@ -3192,9 +3192,9 @@
}
},
"semver": {
- "version": "7.3.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
- "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -3209,12 +3209,12 @@
}
},
"@typescript-eslint/visitor-keys": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.18.0.tgz",
- "integrity": "sha512-Q9t90JCvfYaN0OfFUgaLqByOfz8yPeTAdotn/XYNm5q9eHax90gzdb+RJ6E9T5s97Kv/UHWKERTmqA0jTKAEHw==",
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.19.0.tgz",
+ "integrity": "sha512-aGPS6kz//j7XLSlgpzU2SeTqHPsmRYxFztj2vPuMMFJXZudpRSehE3WCV+BaxwZFvfAqMoSd86TEuM0PQ59E/A==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "4.18.0",
+ "@typescript-eslint/types": "4.19.0",
"eslint-visitor-keys": "^2.0.0"
}
},
diff --git a/packages/bundle/package.json b/packages/bundle/package.json
index e93f9154e4..b761a248ab 100644
--- a/packages/bundle/package.json
+++ b/packages/bundle/package.json
@@ -33,6 +33,7 @@
"adaptivecards": "2.5.0",
"botframework-directlinejs": "0.14.1",
"botframework-directlinespeech-sdk": "0.0.0-0",
+ "botframework-webchat-api": "0.0.0-0",
"botframework-webchat-component": "0.0.0-0",
"botframework-webchat-core": "0.0.0-0",
"classnames": "2.2.6",
@@ -61,8 +62,8 @@
"@babel/preset-typescript": "^7.13.0",
"@types/node": "^14.14.35",
"@types/react": "^16.9.55",
- "@typescript-eslint/eslint-plugin": "^4.18.0",
- "@typescript-eslint/parser": "^4.18.0",
+ "@typescript-eslint/eslint-plugin": "^4.19.0",
+ "@typescript-eslint/parser": "^4.19.0",
"babel-plugin-istanbul": "^6.0.0",
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
"concurrently": "^6.0.0",
diff --git a/packages/bundle/src/FullBundleStyleOptions.ts b/packages/bundle/src/FullBundleStyleOptions.ts
new file mode 100644
index 0000000000..3a1fd94499
--- /dev/null
+++ b/packages/bundle/src/FullBundleStyleOptions.ts
@@ -0,0 +1,9 @@
+import { StrictStyleOptions, StyleOptions } from 'botframework-webchat-api';
+
+import AdaptiveCardStyleOptions, { StrictAdaptiveCardsStyleOptions } from './adaptiveCards/AdaptiveCardsStyleOptions';
+
+type FullBundleStyleOptions = StyleOptions & AdaptiveCardStyleOptions;
+type StrictFullBundleStyleOptions = StrictStyleOptions & StrictAdaptiveCardsStyleOptions;
+
+export default FullBundleStyleOptions;
+export { StrictFullBundleStyleOptions };
diff --git a/packages/bundle/src/adaptiveCards/AdaptiveCardsStyleOptions.ts b/packages/bundle/src/adaptiveCards/AdaptiveCardsStyleOptions.ts
new file mode 100644
index 0000000000..50f69cfb0a
--- /dev/null
+++ b/packages/bundle/src/adaptiveCards/AdaptiveCardsStyleOptions.ts
@@ -0,0 +1,31 @@
+type AdaptiveCardsStyleOptions = {
+ /**
+ * Adaptive Cards styling
+ */
+
+ /**
+ * Adaptive Cards styling for 'emphasis' container style
+ */
+ cardEmphasisBackgroundColor?: string;
+
+ /**
+ * Adaptive Cards: background color of Adaptive Cards button with status of 'aria-pressed'
+ */
+ cardPushButtonBackgroundColor?: string;
+
+ /**
+ * Adaptive Cards: text color of Adaptive Cards button with status of 'aria-pressed'
+ */
+ cardPushButtonTextColor?: string;
+
+ /**
+ * Cards: Rich Cards
+ * Enable title (and subtitle) wrapping
+ */
+ richCardWrapTitle?: boolean;
+};
+
+type StrictAdaptiveCardsStyleOptions = Required;
+
+export default AdaptiveCardsStyleOptions;
+export { StrictAdaptiveCardsStyleOptions };
diff --git a/packages/bundle/src/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.js b/packages/bundle/src/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.ts
similarity index 94%
rename from packages/bundle/src/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.js
rename to packages/bundle/src/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.ts
index d517c0f333..9094f6c0e3 100644
--- a/packages/bundle/src/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.js
+++ b/packages/bundle/src/adaptiveCards/Styles/StyleSet/AdaptiveCardRenderer.ts
@@ -1,10 +1,12 @@
+import FullBundleStyleOptions from '../../../FullBundleStyleOptions';
+
export default function ({
cardPushButtonBackgroundColor,
cardPushButtonTextColor,
accent,
paddingRegular,
primaryFont
-}) {
+}: FullBundleStyleOptions) {
return {
'&.webchat__adaptive-card-renderer': {
'& .ac-input, & .ac-inlineActionButton, & .ac-quickActionButton': {
diff --git a/packages/bundle/src/adaptiveCards/Styles/StyleSet/AudioCardAttachment.js b/packages/bundle/src/adaptiveCards/Styles/StyleSet/AudioCardAttachment.js
index 1b521c5f49..b4e2b3ebb5 100644
--- a/packages/bundle/src/adaptiveCards/Styles/StyleSet/AudioCardAttachment.js
+++ b/packages/bundle/src/adaptiveCards/Styles/StyleSet/AudioCardAttachment.js
@@ -2,7 +2,7 @@
// Later, we will rewrite these attachments without Adaptive Cards
// We are leaving the CSS here as-is for now
-export default function AudioCardAttachment({ paddingRegular }) {
+export default function AudioCardAttachment({ paddingRegular = undefined }) {
return {
// TODO: [P2] We should not set "display" in styleSet, this will allow the user to break the layout for no good reasons.
display: 'flex',
diff --git a/packages/bundle/src/adaptiveCards/Styles/adaptiveCardHostConfig.js b/packages/bundle/src/adaptiveCards/Styles/adaptiveCardHostConfig.js
deleted file mode 100644
index eb938f5b3c..0000000000
--- a/packages/bundle/src/adaptiveCards/Styles/adaptiveCardHostConfig.js
+++ /dev/null
@@ -1,113 +0,0 @@
-import { defaultStyleOptions } from 'botframework-webchat-component';
-// https://docs.microsoft.com/en-us/adaptive-cards/rendering-cards/host-config
-
-export default ({
- accent,
- bubbleTextColor,
- cardEmphasisBackgroundColor,
- primaryFont,
- subtle
-} = defaultStyleOptions) => ({
- containerStyles: {
- default: {
- foregroundColors: {
- default: {
- default: bubbleTextColor,
- subtle
- },
- accent: {
- default: accent,
- subtle: accent
- }
- }
- },
- emphasis: {
- backgroundColor: cardEmphasisBackgroundColor,
- foregroundColors: {
- default: {
- default: bubbleTextColor,
- subtle
- }
- }
- },
- accent: {
- backgroundColor: '#C7DEF9',
- foregroundColors: {
- default: {
- default: '#333333',
- subtle: '#EE333333'
- }
- }
- },
- good: {
- backgroundColor: '#CCFFCC',
- foregroundColors: {
- default: {
- default: '#333333',
- subtle: '#EE333333'
- }
- }
- },
- attention: {
- backgroundColor: '#FFC5B2',
- foregroundColors: {
- default: {
- default: '#333333',
- subtle: '#EE333333'
- }
- }
- },
- warning: {
- backgroundColor: '#FFE2B2',
- foregroundColors: {
- default: {
- default: '#333333',
- subtle: '#EE333333'
- }
- }
- }
- },
- supportsInteractivity: true,
- fontFamily: primaryFont,
- imageSizes: {
- small: 40,
- medium: 80,
- large: 160
- },
- actions: {
- actionAlignment: 'stretch',
- actionsOrientation: 'vertical',
- buttonSpacing: 8,
- maxActions: 100,
- showCard: {
- actionMode: 'inline',
- inlineTopMargin: 8
- },
- spacing: 'default'
- },
- adaptiveCard: {
- allowCustomStyle: false
- },
- imageSet: {
- imageSize: 'medium',
- maxImageHeight: 100
- },
- factSet: {
- title: {
- color: 'default',
- size: 'default',
- isSubtle: false,
- weight: 'bolder',
- wrap: true,
- maxWidth: 150
- },
- value: {
- color: 'default',
- size: 'default',
- isSubtle: false,
- weight: 'default',
- wrap: true
- },
- spacing: 8
- }
-});
diff --git a/packages/bundle/src/adaptiveCards/Styles/adaptiveCardHostConfig.ts b/packages/bundle/src/adaptiveCards/Styles/adaptiveCardHostConfig.ts
new file mode 100644
index 0000000000..42319f4a81
--- /dev/null
+++ b/packages/bundle/src/adaptiveCards/Styles/adaptiveCardHostConfig.ts
@@ -0,0 +1,118 @@
+import { normalizeStyleOptions } from 'botframework-webchat-api';
+
+import FullBundleStyleOptions from '../../FullBundleStyleOptions';
+import normalizeAdaptiveCardsStyleOptions from '../normalizeStyleOptions';
+
+// https://docs.microsoft.com/en-us/adaptive-cards/rendering-cards/host-config
+
+export default function createAdaptiveCardsHostConfig(styleOptions: FullBundleStyleOptions) {
+ const { accent, bubbleTextColor, cardEmphasisBackgroundColor, primaryFont, subtle } = {
+ ...normalizeStyleOptions(styleOptions),
+ ...normalizeAdaptiveCardsStyleOptions(styleOptions)
+ };
+
+ return {
+ containerStyles: {
+ default: {
+ foregroundColors: {
+ default: {
+ default: bubbleTextColor,
+ subtle
+ },
+ accent: {
+ default: accent,
+ subtle: accent
+ }
+ }
+ },
+ emphasis: {
+ backgroundColor: cardEmphasisBackgroundColor,
+ foregroundColors: {
+ default: {
+ default: bubbleTextColor,
+ subtle
+ }
+ }
+ },
+ accent: {
+ backgroundColor: '#C7DEF9',
+ foregroundColors: {
+ default: {
+ default: '#333333',
+ subtle: '#EE333333'
+ }
+ }
+ },
+ good: {
+ backgroundColor: '#CCFFCC',
+ foregroundColors: {
+ default: {
+ default: '#333333',
+ subtle: '#EE333333'
+ }
+ }
+ },
+ attention: {
+ backgroundColor: '#FFC5B2',
+ foregroundColors: {
+ default: {
+ default: '#333333',
+ subtle: '#EE333333'
+ }
+ }
+ },
+ warning: {
+ backgroundColor: '#FFE2B2',
+ foregroundColors: {
+ default: {
+ default: '#333333',
+ subtle: '#EE333333'
+ }
+ }
+ }
+ },
+ supportsInteractivity: true,
+ fontFamily: primaryFont,
+ imageSizes: {
+ small: 40,
+ medium: 80,
+ large: 160
+ },
+ actions: {
+ actionAlignment: 'stretch',
+ actionsOrientation: 'vertical',
+ buttonSpacing: 8,
+ maxActions: 100,
+ showCard: {
+ actionMode: 'inline',
+ inlineTopMargin: 8
+ },
+ spacing: 'default'
+ },
+ adaptiveCard: {
+ allowCustomStyle: false
+ },
+ imageSet: {
+ imageSize: 'medium',
+ maxImageHeight: 100
+ },
+ factSet: {
+ title: {
+ color: 'default',
+ size: 'default',
+ isSubtle: false,
+ weight: 'bolder',
+ wrap: true,
+ maxWidth: 150
+ },
+ value: {
+ color: 'default',
+ size: 'default',
+ isSubtle: false,
+ weight: 'default',
+ wrap: true
+ },
+ spacing: 8
+ }
+ };
+}
diff --git a/packages/bundle/src/adaptiveCards/Styles/createAdaptiveCardsStyleSet.js b/packages/bundle/src/adaptiveCards/Styles/createAdaptiveCardsStyleSet.ts
similarity index 50%
rename from packages/bundle/src/adaptiveCards/Styles/createAdaptiveCardsStyleSet.js
rename to packages/bundle/src/adaptiveCards/Styles/createAdaptiveCardsStyleSet.ts
index fce615b348..762edf4758 100644
--- a/packages/bundle/src/adaptiveCards/Styles/createAdaptiveCardsStyleSet.js
+++ b/packages/bundle/src/adaptiveCards/Styles/createAdaptiveCardsStyleSet.ts
@@ -1,19 +1,24 @@
-import { defaultStyleOptions } from 'botframework-webchat-component';
+import { normalizeStyleOptions, StyleOptions } from 'botframework-webchat-api';
+import AdaptiveCardsStyleOptions from '../AdaptiveCardsStyleOptions';
import createAdaptiveCardRendererStyle from './StyleSet/AdaptiveCardRenderer';
import createAnimationCardAttachmentStyle from './StyleSet/AnimationCardAttachment';
import createAudioCardAttachmentStyle from './StyleSet/AudioCardAttachment';
+import normalizeAdaptiveCardsStyleOptions from '../normalizeStyleOptions';
// TODO: [P4] We should add a notice for people who want to use "styleSet" instead of "styleOptions".
// "styleSet" is actually CSS stylesheet and it is based on the DOM tree.
// DOM tree may change from time to time, thus, maintaining "styleSet" becomes a constant effort.
-export default function createAdaptiveCardsStyleSet(options) {
- options = { ...defaultStyleOptions, ...options };
+export default function createAdaptiveCardsStyleSet(options: StyleOptions & AdaptiveCardsStyleOptions): any {
+ const strictOptions = {
+ ...normalizeStyleOptions(options),
+ ...normalizeAdaptiveCardsStyleOptions(options)
+ };
return {
- adaptiveCardRenderer: createAdaptiveCardRendererStyle(options),
- animationCardAttachment: createAnimationCardAttachmentStyle(options),
- audioCardAttachment: createAudioCardAttachmentStyle(options)
+ adaptiveCardRenderer: createAdaptiveCardRendererStyle(strictOptions),
+ animationCardAttachment: createAnimationCardAttachmentStyle(),
+ audioCardAttachment: createAudioCardAttachmentStyle(strictOptions)
};
}
diff --git a/packages/bundle/src/adaptiveCards/defaultStyleOptions.ts b/packages/bundle/src/adaptiveCards/defaultStyleOptions.ts
new file mode 100644
index 0000000000..3418fe59a6
--- /dev/null
+++ b/packages/bundle/src/adaptiveCards/defaultStyleOptions.ts
@@ -0,0 +1,10 @@
+import AdaptiveCardsStyleOptions from './AdaptiveCardsStyleOptions';
+
+const ADAPTIVE_CARDS_DEFAULT_STYLE_OPTIONS: Required = {
+ cardEmphasisBackgroundColor: '#F0F0F0',
+ cardPushButtonBackgroundColor: '#0063B1',
+ cardPushButtonTextColor: 'white',
+ richCardWrapTitle: false
+};
+
+export default ADAPTIVE_CARDS_DEFAULT_STYLE_OPTIONS;
diff --git a/packages/bundle/src/adaptiveCards/normalizeStyleOptions.ts b/packages/bundle/src/adaptiveCards/normalizeStyleOptions.ts
new file mode 100644
index 0000000000..68c30bef97
--- /dev/null
+++ b/packages/bundle/src/adaptiveCards/normalizeStyleOptions.ts
@@ -0,0 +1,8 @@
+import AdaptiveCardsStyleOptions, { StrictAdaptiveCardsStyleOptions } from './AdaptiveCardsStyleOptions';
+import defaultStyleOptions from './defaultStyleOptions';
+
+export default function normalizeStyleOptions(
+ styleOptions: AdaptiveCardsStyleOptions
+): StrictAdaptiveCardsStyleOptions {
+ return { ...defaultStyleOptions, ...styleOptions };
+}
diff --git a/packages/bundle/src/createFullStyleSet.js b/packages/bundle/src/createFullStyleSet.ts
similarity index 81%
rename from packages/bundle/src/createFullStyleSet.js
rename to packages/bundle/src/createFullStyleSet.ts
index 27ccf4e354..ec96928fa7 100644
--- a/packages/bundle/src/createFullStyleSet.js
+++ b/packages/bundle/src/createFullStyleSet.ts
@@ -1,11 +1,13 @@
import { createStyleSet } from 'botframework-webchat-component';
+import { StyleOptions } from 'botframework-webchat-api';
+
import createAdaptiveCardsStyleSet from './adaptiveCards/Styles/createAdaptiveCardsStyleSet';
// TODO: [P4] We should add a notice for people who want to use "styleSet" instead of "styleOptions".
// "styleSet" is actually CSS stylesheet and it is based on the DOM tree.
// DOM tree may change from time to time, thus, maintaining "styleSet" becomes a constant effort.
-export default function createFullStyleSet(options) {
+export default function createFullStyleSet(options: StyleOptions) {
return {
...createStyleSet(options),
...createAdaptiveCardsStyleSet(options)
diff --git a/packages/bundle/src/fullBundleDefaultStyleOptions.ts b/packages/bundle/src/fullBundleDefaultStyleOptions.ts
new file mode 100644
index 0000000000..764dd19fe3
--- /dev/null
+++ b/packages/bundle/src/fullBundleDefaultStyleOptions.ts
@@ -0,0 +1,11 @@
+import { defaultStyleOptions } from 'botframework-webchat-api';
+import adaptiveCardsDefaultStyleOptions from './adaptiveCards/defaultStyleOptions';
+
+import FullBundleStyleOptions from './FullBundleStyleOptions';
+
+const FULL_BUNDLE_DEFAULT_STYLE_OPTIONS: Required = {
+ ...defaultStyleOptions,
+ ...adaptiveCardsDefaultStyleOptions
+};
+
+export default FULL_BUNDLE_DEFAULT_STYLE_OPTIONS;
diff --git a/packages/bundle/src/index-es5.ts b/packages/bundle/src/index-es5.ts
index 313d011e08..4fe7301f7c 100644
--- a/packages/bundle/src/index-es5.ts
+++ b/packages/bundle/src/index-es5.ts
@@ -1,3 +1,5 @@
+// IMPORTANT: To export anything from this file, add it to index-es5.tsx, which is the .d.ts for this file.
+
/* eslint dot-notation: ["error", { "allowPattern": "^WebChat$" }] */
// window['WebChat'] is required for TypeScript
diff --git a/packages/bundle/src/index-es5.tsx b/packages/bundle/src/index-es5.tsx
new file mode 100644
index 0000000000..4294c2c2c8
--- /dev/null
+++ b/packages/bundle/src/index-es5.tsx
@@ -0,0 +1,49 @@
+import { FC } from 'react';
+import {
+ Components as ComponentsFromComponent,
+ ComposerProps,
+ ReactWebChatProps
+} from 'botframework-webchat-component';
+
+import StyleOptions from './FullBundleStyleOptions';
+
+type Replace = Omit & T2;
+
+/** Creates a set of styles with support of Adaptive Cards */
+declare function createStyleSet(styleOptions: StyleOptions): any;
+
+declare const Components: Omit & {
+ Composer: FC<
+ Replace<
+ ComposerProps,
+ {
+ /** Style options with support of Adaptive Cards */
+ styleOptions?: StyleOptions;
+ }
+ >
+ >;
+};
+
+/** React-based Web Chat with support of Adaptive Cards */
+declare const ReactWebChat: FC<
+ Replace<
+ ReactWebChatProps,
+ {
+ /** Style options with support of Adaptive Cards */
+ styleOptions?: StyleOptions;
+ }
+ >
+>;
+
+export default ReactWebChat;
+export { Components, createStyleSet };
+export type { StyleOptions };
+
+// Doc:
+// - We don't want to export the whole index.ts, we just want to export what the user actually needed
+// - That's why we only exporting index.tsx (we cannot name it index.d.ts because TSC won't pick it up)
+// - Changing between full bundle and minimal should be very smooth
+// - That's why we name both StyleOptions the same
+// - To use minimal, import 'botframework-webchat/lib/index-minimal';
+// - Declarations need to be emitted to /lib/*.d.ts for code-splitting purpose
+// - import 'botframework-webchat/lib/index-minimal' should see IntelliSense support
diff --git a/packages/bundle/src/index-minimal.ts b/packages/bundle/src/index-minimal.ts
index 1284f045c9..ae74bf8d10 100644
--- a/packages/bundle/src/index-minimal.ts
+++ b/packages/bundle/src/index-minimal.ts
@@ -1,3 +1,5 @@
+// IMPORTANT: To export anything from this file, add it to index-minimal.tsx, which is the .d.ts for this file.
+
/* eslint dot-notation: ["error", { "allowPattern": "^WebChat$" }] */
// window['WebChat'] is required for TypeScript
diff --git a/packages/bundle/src/index-minimal.tsx b/packages/bundle/src/index-minimal.tsx
new file mode 100644
index 0000000000..e9c84c76ee
--- /dev/null
+++ b/packages/bundle/src/index-minimal.tsx
@@ -0,0 +1,9 @@
+import { StyleOptions } from 'botframework-webchat-api';
+import ReactWebChat, { Components } from 'botframework-webchat-component';
+
+/** Creates a set of styles */
+declare function createStyleSet(styleOptions: StyleOptions): any;
+
+export default ReactWebChat;
+export { Components, createStyleSet };
+export type { StyleOptions };
diff --git a/packages/bundle/src/index.ts b/packages/bundle/src/index.ts
index fc0e483c2f..92beb6d471 100644
--- a/packages/bundle/src/index.ts
+++ b/packages/bundle/src/index.ts
@@ -1,3 +1,5 @@
+// IMPORTANT: To export anything from this file, add it to index.tsx, which is the .d.ts for this file.
+
/* eslint dot-notation: ["error", { "allowPattern": "^WebChat$" }] */
// window['WebChat'] is required for TypeScript
diff --git a/packages/bundle/src/index.tsx b/packages/bundle/src/index.tsx
new file mode 100644
index 0000000000..8eb0019032
--- /dev/null
+++ b/packages/bundle/src/index.tsx
@@ -0,0 +1,45 @@
+import { FC } from 'react';
+import { ComposerProps, ReactWebChatProps } from 'botframework-webchat-component';
+
+import StyleOptions from './FullBundleStyleOptions';
+
+type Replace = Omit & T2;
+
+/** Creates a set of styles with support of Adaptive Cards */
+declare function createStyleSet(styleOptions: StyleOptions): any;
+
+declare const Components: {
+ Composer: FC<
+ Replace<
+ ComposerProps,
+ {
+ /** Style options with support of Adaptive Cards */
+ styleOptions?: StyleOptions;
+ }
+ >
+ >;
+};
+
+/** React-based Web Chat with support of Adaptive Cards */
+declare const ReactWebChat: FC<
+ Replace<
+ ReactWebChatProps,
+ {
+ /** Style options with support of Adaptive Cards */
+ styleOptions?: StyleOptions;
+ }
+ >
+>;
+
+export default ReactWebChat;
+export { Components, createStyleSet };
+export type { StyleOptions };
+
+// Doc:
+// - We don't want to export the whole index.ts, we just want to export what the user actually needed
+// - That's why we only exporting index.tsx (we cannot name it index.d.ts because TSC won't pick it up)
+// - Changing between full bundle and minimal should be very smooth
+// - That's why we name both StyleOptions the same
+// - To use minimal, import 'botframework-webchat/lib/index-minimal';
+// - Declarations need to be emitted to /lib/*.d.ts for code-splitting purpose
+// - import 'botframework-webchat/lib/index-minimal' should see IntelliSense support
diff --git a/packages/bundle/src/tsconfig.json b/packages/bundle/src/tsconfig.json
index ca32a35acf..67687e45e4 100644
--- a/packages/bundle/src/tsconfig.json
+++ b/packages/bundle/src/tsconfig.json
@@ -3,11 +3,13 @@
"allowSyntheticDefaultImports": true,
"declaration": true,
"declarationDir": "../lib",
+ "declarationMap": true,
"emitDeclarationOnly": true,
- "isolatedModules": true,
"jsx": "react",
"preserveWatchOutput": true,
"pretty": true,
- "skipLibCheck": true
- }
+ "skipLibCheck": true,
+ "sourceMap": true
+ },
+ "files": ["index.tsx", "index-es5.tsx", "index-minimal.tsx"]
}
diff --git a/packages/bundle/src/useComposerProps.js b/packages/bundle/src/useComposerProps.js
index c1222e68e3..a0afa9ba57 100644
--- a/packages/bundle/src/useComposerProps.js
+++ b/packages/bundle/src/useComposerProps.js
@@ -1,6 +1,6 @@
+import { concatMiddleware } from 'botframework-webchat-component';
import { useMemo } from 'react';
-import { concatMiddleware, defaultStyleOptions } from 'botframework-webchat-component';
import createAdaptiveCardsAttachmentForScreenReaderMiddleware from './adaptiveCards/createAdaptiveCardsAttachmentForScreenReaderMiddleware';
import createAdaptiveCardsAttachmentMiddleware from './adaptiveCards/createAdaptiveCardsAttachmentMiddleware';
import createAdaptiveCardsStyleSet from './adaptiveCards/Styles/createAdaptiveCardsStyleSet';
@@ -24,11 +24,9 @@ export default function useComposerProps({
[attachmentForScreenReaderMiddleware]
);
- const patchedStyleOptions = useMemo(() => ({ ...defaultStyleOptions, ...styleOptions }), [styleOptions]);
-
// When styleSet is not specified, the styleOptions will be used to create Adaptive Cards styleSet and merged into useStyleSet.
- const extraStyleSet = useMemo(() => (styleSet ? undefined : createAdaptiveCardsStyleSet(patchedStyleOptions)), [
- patchedStyleOptions,
+ const extraStyleSet = useMemo(() => (styleSet ? undefined : createAdaptiveCardsStyleSet(styleOptions)), [
+ styleOptions,
styleSet
]);
diff --git a/packages/component/.eslintrc.yml b/packages/component/.eslintrc.yml
index 3d1c9cc36d..1046d75635 100644
--- a/packages/component/.eslintrc.yml
+++ b/packages/component/.eslintrc.yml
@@ -3,6 +3,9 @@ extends:
plugins:
- prettier
- react-hooks
+- '@typescript-eslint/eslint-plugin'
+parser:
+ '@typescript-eslint/parser'
rules:
# plugins
prettier/prettier: error
@@ -89,3 +92,11 @@ rules:
react/jsx-wrap-multilines: error # Conflict with no-extra-parens
react-hooks/rules-of-hooks: error
react-hooks/exhaustive-deps: warn
+
+ # TypeScript
+
+ # The correct way to use with typescript-eslint is to disable the core version.
+ # https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-use-before-define.md#how-to-use
+ no-use-before-define: off
+ '@typescript-eslint/no-use-before-define':
+ - error
diff --git a/packages/component/babel.config.json b/packages/component/babel.config.json
index cfadc9c45f..9ea0a28993 100644
--- a/packages/component/babel.config.json
+++ b/packages/component/babel.config.json
@@ -5,6 +5,7 @@
"plugins": ["babel-plugin-istanbul"]
}
},
+ "ignore": ["src/index.tsx"],
"overrides": [
{
"plugins": [],
diff --git a/packages/component/package-lock.json b/packages/component/package-lock.json
index 98a96a9487..9e640d7a2a 100644
--- a/packages/component/package-lock.json
+++ b/packages/component/package-lock.json
@@ -3553,6 +3553,32 @@
"upath": "^1.1.1"
}
},
+ "@nodelib/fs.scandir": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
+ "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.4",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz",
+ "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz",
+ "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.4",
+ "fastq": "^1.6.0"
+ }
+ },
"@types/json-schema": {
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
@@ -3608,6 +3634,141 @@
"vfile-message": "*"
}
},
+ "@typescript-eslint/eslint-plugin": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.19.0.tgz",
+ "integrity": "sha512-CRQNQ0mC2Pa7VLwKFbrGVTArfdVDdefS+gTw0oC98vSI98IX5A8EVH4BzJ2FOB0YlCmm8Im36Elad/Jgtvveaw==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/experimental-utils": "4.19.0",
+ "@typescript-eslint/scope-manager": "4.19.0",
+ "debug": "^4.1.1",
+ "functional-red-black-tree": "^1.0.1",
+ "lodash": "^4.17.15",
+ "regexpp": "^3.0.0",
+ "semver": "^7.3.2",
+ "tsutils": "^3.17.1"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ }
+ }
+ },
+ "@typescript-eslint/experimental-utils": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.19.0.tgz",
+ "integrity": "sha512-9/23F1nnyzbHKuoTqFN1iXwN3bvOm/PRIXSBR3qFAYotK/0LveEOHr5JT1WZSzcD6BESl8kPOG3OoDRKO84bHA==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.3",
+ "@typescript-eslint/scope-manager": "4.19.0",
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/typescript-estree": "4.19.0",
+ "eslint-scope": "^5.0.0",
+ "eslint-utils": "^2.0.0"
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.19.0.tgz",
+ "integrity": "sha512-/uabZjo2ZZhm66rdAu21HA8nQebl3lAIDcybUoOxoI7VbZBYavLIwtOOmykKCJy+Xq6Vw6ugkiwn8Js7D6wieA==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/scope-manager": "4.19.0",
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/typescript-estree": "4.19.0",
+ "debug": "^4.1.1"
+ }
+ },
+ "@typescript-eslint/scope-manager": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.19.0.tgz",
+ "integrity": "sha512-GGy4Ba/hLXwJXygkXqMzduqOMc+Na6LrJTZXJWVhRrSuZeXmu8TAnniQVKgj8uTRKe4igO2ysYzH+Np879G75g==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/visitor-keys": "4.19.0"
+ }
+ },
+ "@typescript-eslint/types": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.19.0.tgz",
+ "integrity": "sha512-A4iAlexVvd4IBsSTNxdvdepW0D4uR/fwxDrKUa+iEY9UWvGREu2ZyB8ylTENM1SH8F7bVC9ac9+si3LWNxcBuA==",
+ "dev": true
+ },
+ "@typescript-eslint/typescript-estree": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.19.0.tgz",
+ "integrity": "sha512-3xqArJ/A62smaQYRv2ZFyTA+XxGGWmlDYrsfZG68zJeNbeqRScnhf81rUVa6QG4UgzHnXw5VnMT5cg75dQGDkA==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.19.0",
+ "@typescript-eslint/visitor-keys": "4.19.0",
+ "debug": "^4.1.1",
+ "globby": "^11.0.1",
+ "is-glob": "^4.0.1",
+ "semver": "^7.3.2",
+ "tsutils": "^3.17.1"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ }
+ }
+ },
+ "@typescript-eslint/visitor-keys": {
+ "version": "4.19.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.19.0.tgz",
+ "integrity": "sha512-aGPS6kz//j7XLSlgpzU2SeTqHPsmRYxFztj2vPuMMFJXZudpRSehE3WCV+BaxwZFvfAqMoSd86TEuM0PQ59E/A==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.19.0",
+ "eslint-visitor-keys": "^2.0.0"
+ }
+ },
"@webassemblyjs/ast": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
@@ -3913,6 +4074,12 @@
}
}
},
+ "array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true
+ },
"array-unique": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
@@ -4207,6 +4374,15 @@
"integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
"optional": true
},
+ "bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "optional": true,
+ "requires": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -5180,6 +5356,15 @@
}
}
},
+ "dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "requires": {
+ "path-type": "^4.0.0"
+ }
+ },
"doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@@ -6037,6 +6222,74 @@
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
"dev": true
},
+ "fast-glob": {
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
+ "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.0",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.2",
+ "picomatch": "^2.2.1"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -6048,6 +6301,15 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
+ "fastq": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz",
+ "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
"fbjs": {
"version": "0.8.17",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
@@ -6083,6 +6345,12 @@
"flat-cache": "^3.0.4"
}
},
+ "file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "optional": true
+ },
"filewatcher": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/filewatcher/-/filewatcher-3.0.1.tgz",
@@ -6371,6 +6639,34 @@
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
},
+ "globby": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz",
+ "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==",
+ "dev": true,
+ "requires": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.1.1",
+ "ignore": "^5.1.4",
+ "merge2": "^1.3.0",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ }
+ }
+ },
"graceful-fs": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
@@ -7271,6 +7567,12 @@
"readable-stream": "^2.0.1"
}
},
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
+ },
"micromatch": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@@ -7392,6 +7694,12 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
+ "nan": {
+ "version": "2.14.2",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
+ "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+ "optional": true
+ },
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@@ -7899,6 +8207,12 @@
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
},
+ "path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true
+ },
"pbkdf2": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
@@ -7914,8 +8228,7 @@
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
- "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
- "optional": true
+ "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg=="
},
"pify": {
"version": "4.0.1",
@@ -8090,6 +8403,12 @@
"resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
"integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
},
+ "queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true
+ },
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -8511,6 +8830,12 @@
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
},
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true
+ },
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
@@ -8528,6 +8853,15 @@
"inherits": "^2.0.1"
}
},
+ "run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "requires": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
"run-queue": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
@@ -9457,6 +9791,15 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q=="
},
+ "tsutils": {
+ "version": "3.21.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+ "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ }
+ },
"tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -9828,7 +10171,11 @@
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
- "optional": true
+ "optional": true,
+ "requires": {
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
+ }
}
}
},
diff --git a/packages/component/package.json b/packages/component/package.json
index 4b75a25e13..c41e02da20 100644
--- a/packages/component/package.json
+++ b/packages/component/package.json
@@ -3,6 +3,7 @@
"version": "0.0.0-0",
"description": "React component of botframework-webchat",
"main": "lib/index.js",
+ "typings": "lib/index.d.ts",
"publishConfig": {
"access": "public"
},
@@ -34,6 +35,8 @@
"@babel/preset-typescript": "^7.13.0",
"@types/node": "^14.14.35",
"@types/react": "^16.9.55",
+ "@typescript-eslint/eslint-plugin": "^4.19.0",
+ "@typescript-eslint/parser": "^4.19.0",
"babel-plugin-istanbul": "^6.0.0",
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
"concurrently": "^6.0.0",
diff --git a/packages/component/src/BasicTranscript.js b/packages/component/src/BasicTranscript.js
index d1a55b079f..a3231ab9b7 100644
--- a/packages/component/src/BasicTranscript.js
+++ b/packages/component/src/BasicTranscript.js
@@ -265,7 +265,7 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
let showCallout;
- // Depends on different "showAvatarInGroup" setting, we will show the avatar in different positions.
+ // Depending on the "showAvatarInGroup" setting, the avatar will render in different positions.
if (showAvatarInGroup === 'sender') {
if (topSideNub) {
showCallout = firstInSenderGroup && firstInSenderAndStatusGroup;
@@ -766,6 +766,8 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
))}
+ {/* TODO: [P2] Fix ESLint error `no-use-before-define` */}
+ {/* eslint-disable-next-line @typescript-eslint/no-use-before-define */}
.bubble-box': {
- maxWidth: bubbleMaxWidth,
- minWidth: bubbleMinWidth
- },
-
- '& > .filler': {
- minWidth: paddingRegular
- }
- };
-}
diff --git a/packages/component/src/Styles/StyleSet/SingleAttachmentActivity.ts b/packages/component/src/Styles/StyleSet/SingleAttachmentActivity.ts
new file mode 100644
index 0000000000..1e28a7bfac
--- /dev/null
+++ b/packages/component/src/Styles/StyleSet/SingleAttachmentActivity.ts
@@ -0,0 +1,18 @@
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
+export default function createSingleCardActivityStyle({
+ bubbleMaxWidth,
+ bubbleMinWidth,
+ paddingRegular
+}: StrictStyleOptions) {
+ return {
+ '& > .bubble-box': {
+ maxWidth: bubbleMaxWidth,
+ minWidth: bubbleMinWidth
+ },
+
+ '& > .filler': {
+ minWidth: paddingRegular
+ }
+ };
+}
diff --git a/packages/component/src/Styles/StyleSet/SpinnerAnimation.js b/packages/component/src/Styles/StyleSet/SpinnerAnimation.ts
similarity index 99%
rename from packages/component/src/Styles/StyleSet/SpinnerAnimation.js
rename to packages/component/src/Styles/StyleSet/SpinnerAnimation.ts
index f3dc5158ed..293add109a 100644
--- a/packages/component/src/Styles/StyleSet/SpinnerAnimation.js
+++ b/packages/component/src/Styles/StyleSet/SpinnerAnimation.ts
@@ -1,3 +1,5 @@
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
import { toByteArray } from 'base64-js';
const DEFAULT_IMAGE_BASE64 =
@@ -11,7 +13,7 @@ export default function createSpinnerAnimationStyle({
spinnerAnimationHeight,
spinnerAnimationWidth,
spinnerAnimationPadding
-}) {
+}: StrictStyleOptions) {
defaultImageBlobURL ||
(defaultImageBlobURL = URL.createObjectURL(
new Blob([toByteArray(DEFAULT_IMAGE_BASE64)], { type: DEFAULT_IMAGE_TYPE })
diff --git a/packages/component/src/Styles/StyleSet/StackedLayout.js b/packages/component/src/Styles/StyleSet/StackedLayout.ts
similarity index 96%
rename from packages/component/src/Styles/StyleSet/StackedLayout.js
rename to packages/component/src/Styles/StyleSet/StackedLayout.ts
index 2d38ceb025..78f8b59280 100644
--- a/packages/component/src/Styles/StyleSet/StackedLayout.js
+++ b/packages/component/src/Styles/StyleSet/StackedLayout.ts
@@ -1,12 +1,14 @@
/* eslint no-magic-numbers: ["error", { "ignore": [2] }] */
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
export default function createStackedLayoutStyle({
avatarSize,
bubbleMaxWidth,
bubbleMinWidth,
paddingRegular,
transitionDuration
-}) {
+}: StrictStyleOptions) {
return {
'&.webchat__stacked-layout': {
marginLeft: paddingRegular,
diff --git a/packages/component/src/Styles/StyleSet/SuggestedAction.js b/packages/component/src/Styles/StyleSet/SuggestedAction.ts
similarity index 96%
rename from packages/component/src/Styles/StyleSet/SuggestedAction.js
rename to packages/component/src/Styles/StyleSet/SuggestedAction.ts
index a51bbf2fc4..ac37d16fbb 100644
--- a/packages/component/src/Styles/StyleSet/SuggestedAction.js
+++ b/packages/component/src/Styles/StyleSet/SuggestedAction.ts
@@ -1,5 +1,7 @@
/* eslint no-magic-numbers: "off" */
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
export default function createSuggestedActionStyle({
accent,
paddingRegular,
@@ -20,7 +22,7 @@ export default function createSuggestedActionStyle({
suggestedActionHeight,
suggestedActionsStackedLayoutButtonMaxHeight,
subtle
-}) {
+}: StrictStyleOptions) {
return {
'&.webchat__suggested-action': {
display: 'flex',
diff --git a/packages/component/src/Styles/StyleSet/SuggestedActions.js b/packages/component/src/Styles/StyleSet/SuggestedActions.ts
similarity index 98%
rename from packages/component/src/Styles/StyleSet/SuggestedActions.js
rename to packages/component/src/Styles/StyleSet/SuggestedActions.ts
index 121d0cd5a1..48d631c042 100644
--- a/packages/component/src/Styles/StyleSet/SuggestedActions.js
+++ b/packages/component/src/Styles/StyleSet/SuggestedActions.ts
@@ -1,6 +1,8 @@
/* eslint no-empty-pattern: "off" */
/* eslint no-magic-numbers: ["error", { "ignore": [1.5, 2] }] */
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
export default function createSuggestedActionsStyle({
paddingRegular,
suggestedActionsCarouselFlipperSize,
@@ -15,7 +17,7 @@ export default function createSuggestedActionsStyle({
transcriptOverlayButtonColorOnDisabled,
transcriptOverlayButtonColorOnFocus,
transcriptOverlayButtonColorOnHover
-}) {
+}: StrictStyleOptions) {
return {
'&.webchat__suggested-actions': {
'&.webchat__suggested-actions--carousel-layout': {
diff --git a/packages/component/src/Styles/StyleSet/TextContent.js b/packages/component/src/Styles/StyleSet/TextContent.ts
similarity index 90%
rename from packages/component/src/Styles/StyleSet/TextContent.js
rename to packages/component/src/Styles/StyleSet/TextContent.ts
index 6aef395d91..11eddddc78 100644
--- a/packages/component/src/Styles/StyleSet/TextContent.js
+++ b/packages/component/src/Styles/StyleSet/TextContent.ts
@@ -1,12 +1,14 @@
/* eslint no-magic-numbers: "off" */
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
export default function createTextContentStyle({
bubbleMaxWidth,
bubbleMinHeight,
markdownExternalLinkIconImage,
primaryFont,
paddingRegular
-}) {
+}: StrictStyleOptions) {
return {
fontFamily: primaryFont,
margin: 0,
diff --git a/packages/component/src/Styles/StyleSet/Toast.js b/packages/component/src/Styles/StyleSet/Toast.ts
similarity index 95%
rename from packages/component/src/Styles/StyleSet/Toast.js
rename to packages/component/src/Styles/StyleSet/Toast.ts
index 7b07f97ab6..6ee99e58be 100644
--- a/packages/component/src/Styles/StyleSet/Toast.js
+++ b/packages/component/src/Styles/StyleSet/Toast.ts
@@ -1,4 +1,5 @@
/* eslint no-magic-numbers: ["off"] */
+import { StrictStyleOptions } from 'botframework-webchat-api';
export default function createToastStyle({
primaryFont,
@@ -10,7 +11,7 @@ export default function createToastStyle({
toastSuccessColor,
toastTextPadding,
toastWarnColor
-}) {
+}: StrictStyleOptions) {
return {
fontFamily: primaryFont,
fontSize: toastFontSize,
diff --git a/packages/component/src/Styles/StyleSet/Toaster.js b/packages/component/src/Styles/StyleSet/Toaster.ts
similarity index 97%
rename from packages/component/src/Styles/StyleSet/Toaster.js
rename to packages/component/src/Styles/StyleSet/Toaster.ts
index 31d341c0cc..42df1c28fb 100644
--- a/packages/component/src/Styles/StyleSet/Toaster.js
+++ b/packages/component/src/Styles/StyleSet/Toaster.ts
@@ -1,5 +1,7 @@
/* eslint no-magic-numbers: ["off"] */
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
export default function createToasterStyle({
primaryFont,
toasterHeight,
@@ -16,7 +18,7 @@ export default function createToasterStyle({
toastSuccessColor,
toastWarnBackgroundColor,
toastWarnColor
-}) {
+}: StrictStyleOptions) {
return {
overflowY: 'hidden',
diff --git a/packages/component/src/Styles/StyleSet/TypingAnimation.js b/packages/component/src/Styles/StyleSet/TypingAnimation.ts
similarity index 98%
rename from packages/component/src/Styles/StyleSet/TypingAnimation.js
rename to packages/component/src/Styles/StyleSet/TypingAnimation.ts
index d9b2ee77b1..132672e61c 100644
--- a/packages/component/src/Styles/StyleSet/TypingAnimation.js
+++ b/packages/component/src/Styles/StyleSet/TypingAnimation.ts
@@ -1,3 +1,4 @@
+import { StrictStyleOptions } from 'botframework-webchat-api';
import { toByteArray } from 'base64-js';
const DEFAULT_IMAGE_BASE64 =
@@ -10,7 +11,7 @@ export default function createTypingAnimationStyle({
typingAnimationBackgroundImage,
typingAnimationHeight,
typingAnimationWidth
-}) {
+}: StrictStyleOptions) {
defaultImageBlobURL ||
(defaultImageBlobURL = URL.createObjectURL(
new Blob([toByteArray(DEFAULT_IMAGE_BASE64)], { type: DEFAULT_IMAGE_TYPE })
diff --git a/packages/component/src/Styles/StyleSet/TypingIndicator.js b/packages/component/src/Styles/StyleSet/TypingIndicator.ts
similarity index 75%
rename from packages/component/src/Styles/StyleSet/TypingIndicator.js
rename to packages/component/src/Styles/StyleSet/TypingIndicator.ts
index c615238eac..3101161da4 100644
--- a/packages/component/src/Styles/StyleSet/TypingIndicator.js
+++ b/packages/component/src/Styles/StyleSet/TypingIndicator.ts
@@ -1,4 +1,6 @@
-export default function createTypingIndicatorStyle({ paddingRegular }) {
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
+export default function createTypingIndicatorStyle({ paddingRegular }: StrictStyleOptions) {
return {
paddingBottom: paddingRegular,
diff --git a/packages/component/src/Styles/StyleSet/UploadButton.js b/packages/component/src/Styles/StyleSet/UploadButton.ts
similarity index 84%
rename from packages/component/src/Styles/StyleSet/UploadButton.js
rename to packages/component/src/Styles/StyleSet/UploadButton.ts
index 923a09b0ba..b1136ebde9 100644
--- a/packages/component/src/Styles/StyleSet/UploadButton.js
+++ b/packages/component/src/Styles/StyleSet/UploadButton.ts
@@ -1,10 +1,12 @@
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
export default function createUploadButtonStyle({
sendBoxButtonColor,
sendBoxButtonColorOnFocus,
sendBoxButtonColorOnHover,
sendBoxHeight,
subtle
-}) {
+}: StrictStyleOptions) {
return {
// We use the sendBoxHeight, so the button looks square
width: sendBoxHeight,
diff --git a/packages/component/src/Styles/StyleSet/VideoAttachment.js b/packages/component/src/Styles/StyleSet/VideoAttachment.ts
similarity index 100%
rename from packages/component/src/Styles/StyleSet/VideoAttachment.js
rename to packages/component/src/Styles/StyleSet/VideoAttachment.ts
diff --git a/packages/component/src/Styles/StyleSet/VideoContent.js b/packages/component/src/Styles/StyleSet/VideoContent.js
deleted file mode 100644
index e8a5796680..0000000000
--- a/packages/component/src/Styles/StyleSet/VideoContent.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default function createVideoContentStyle({ videoHeight }) {
- return {
- height: videoHeight,
- width: '100%'
- };
-}
diff --git a/packages/component/src/Styles/StyleSet/VideoContent.ts b/packages/component/src/Styles/StyleSet/VideoContent.ts
new file mode 100644
index 0000000000..9c23dcda52
--- /dev/null
+++ b/packages/component/src/Styles/StyleSet/VideoContent.ts
@@ -0,0 +1,8 @@
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
+export default function createVideoContentStyle({ videoHeight }: StrictStyleOptions) {
+ return {
+ height: videoHeight,
+ width: '100%'
+ };
+}
diff --git a/packages/component/src/Styles/StyleSet/VimeoContent.js b/packages/component/src/Styles/StyleSet/VimeoContent.js
deleted file mode 100644
index 4be04a759d..0000000000
--- a/packages/component/src/Styles/StyleSet/VimeoContent.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default function createVimeoContentStyle({ videoHeight }) {
- return {
- border: 0,
- height: videoHeight,
- width: '100%'
- };
-}
diff --git a/packages/component/src/Styles/StyleSet/VimeoContent.ts b/packages/component/src/Styles/StyleSet/VimeoContent.ts
new file mode 100644
index 0000000000..02e2764862
--- /dev/null
+++ b/packages/component/src/Styles/StyleSet/VimeoContent.ts
@@ -0,0 +1,9 @@
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
+export default function createVimeoContentStyle({ videoHeight }: StrictStyleOptions) {
+ return {
+ border: 0,
+ height: videoHeight,
+ width: '100%'
+ };
+}
diff --git a/packages/component/src/Styles/StyleSet/WarningNotification.js b/packages/component/src/Styles/StyleSet/WarningNotification.ts
similarity index 91%
rename from packages/component/src/Styles/StyleSet/WarningNotification.js
rename to packages/component/src/Styles/StyleSet/WarningNotification.ts
index f00e105122..7ec46b92a6 100644
--- a/packages/component/src/Styles/StyleSet/WarningNotification.js
+++ b/packages/component/src/Styles/StyleSet/WarningNotification.ts
@@ -1,3 +1,5 @@
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
export default function createWarningNotificationStyle({
connectivityIconPadding,
connectivityMarginLeftRight,
@@ -6,7 +8,7 @@ export default function createWarningNotificationStyle({
primaryFont,
slowConnectivity,
notificationText
-}) {
+}: StrictStyleOptions) {
return {
alignItems: 'center',
color: notificationText,
diff --git a/packages/component/src/Styles/StyleSet/YouTubeContent.js b/packages/component/src/Styles/StyleSet/YouTubeContent.ts
similarity index 61%
rename from packages/component/src/Styles/StyleSet/YouTubeContent.js
rename to packages/component/src/Styles/StyleSet/YouTubeContent.ts
index fe4aa4cb95..27cfd14749 100644
--- a/packages/component/src/Styles/StyleSet/YouTubeContent.js
+++ b/packages/component/src/Styles/StyleSet/YouTubeContent.ts
@@ -1,4 +1,6 @@
-export default function createYouTubeContentStyle({ videoHeight }) {
+import { StrictStyleOptions } from 'botframework-webchat-api';
+
+export default function createYouTubeContentStyle({ videoHeight }: StrictStyleOptions) {
return {
border: 0,
height: videoHeight,
diff --git a/packages/component/src/Styles/createStyleSet.js b/packages/component/src/Styles/createStyleSet.ts
similarity index 74%
rename from packages/component/src/Styles/createStyleSet.js
rename to packages/component/src/Styles/createStyleSet.ts
index 957291a155..45f913daac 100644
--- a/packages/component/src/Styles/createStyleSet.js
+++ b/packages/component/src/Styles/createStyleSet.ts
@@ -1,4 +1,6 @@
/* eslint-disable complexity */
+import { normalizeStyleOptions, StyleOptions } from 'botframework-webchat-api';
+
import createActivitiesStyle from './StyleSet/Activities';
import createAudioAttachmentStyle from './StyleSet/AudioAttachment';
import createAudioContentStyle from './StyleSet/AudioContent';
@@ -39,69 +41,17 @@ import createVimeoContentStyle from './StyleSet/VimeoContent';
import createWarningNotificationStyle from './StyleSet/WarningNotification';
import createYouTubeContentStyle from './StyleSet/YouTubeContent';
-import defaultStyleOptions from './defaultStyleOptions';
-
// TODO: [P4] We should add a notice for people who want to use "styleSet" instead of "styleOptions".
// "styleSet" is actually CSS stylesheet and it is based on the DOM tree.
// DOM tree may change from time to time, thus, maintaining "styleSet" becomes a constant effort.
-export default function createStyleSet(options) {
- options = { ...defaultStyleOptions, ...options };
-
- // Keep this list flat (no nested style) and serializable (no functions)
-
- // TODO: [P4] Deprecate this code after bump to v5
- const { bubbleFromUserNubOffset, bubbleNubOffset } = options;
-
- if (bubbleFromUserNubOffset === 'top') {
- options.bubbleFromUserNubOffset = 0;
- } else if (typeof bubbleFromUserNubOffset !== 'number') {
- options.bubbleFromUserNubOffset = -0;
- }
-
- if (bubbleNubOffset === 'top') {
- options.bubbleNubOffset = 0;
- } else if (typeof bubbleNubOffset !== 'number') {
- options.bubbleNubOffset = -0;
- }
-
- if (options.emojiSet === true) {
- options.emojiSet = {
- ':)': 'đ',
- ':-)': 'đ',
- '(:': 'đ',
- '(-:': 'đ',
- ':-|': 'đ',
- ':|': 'đ',
- ':-(': 'âšī¸',
- ':(': 'âšī¸',
- ':-D': 'đ',
- ':D': 'đ',
- ':-p': 'đ',
- ':p': 'đ',
- ':-P': 'đ',
- ':P': 'đ',
- ':-o': 'đ˛',
- ':o': 'đ˛',
- ':O': 'đ˛',
- ':-O': 'đ˛',
- ':-0': 'đ˛',
- ':0': 'đ˛',
- ';-)': 'đ',
- ';)': 'đ',
- '<3': 'â¤ī¸',
- '3': 'đ',
- '<\\3': 'đ'
- };
- } else if (Object.prototype.toString.call(options.emojiSet) !== '[object Object]') {
- console.warn('botframework-webchat: emojiSet must be a boolean or an object with emoticon: emojiValues');
- options.emojiSet = false;
- }
+export default function createStyleSet(options: StyleOptions) {
+ options = normalizeStyleOptions(options);
return {
- activities: createActivitiesStyle(options),
+ activities: createActivitiesStyle(),
audioAttachment: createAudioAttachmentStyle(options),
- audioContent: createAudioContentStyle(options),
+ audioContent: createAudioContentStyle(),
autoResizeTextArea: createAutoResizeTextAreaStyle(options),
avatar: createAvatarStyle(options),
basicTranscript: createBasicTranscriptStyle(options),
@@ -134,7 +84,7 @@ export default function createStyleSet(options) {
typingAnimation: createTypingAnimationStyle(options),
typingIndicator: createTypingIndicatorStyle(options),
uploadButton: createUploadButtonStyle(options),
- videoAttachment: createVideoAttachmentStyle(options),
+ videoAttachment: createVideoAttachmentStyle(),
videoContent: createVideoContentStyle(options),
vimeoContent: createVimeoContentStyle(options),
warningNotification: createWarningNotificationStyle(options),
diff --git a/packages/component/src/Styles/defaultStyleOptions.js b/packages/component/src/Styles/defaultStyleOptions.js
deleted file mode 100644
index 5c069eba12..0000000000
--- a/packages/component/src/Styles/defaultStyleOptions.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/* eslint no-magic-numbers: "off" */
-
-function fontFamily(fonts) {
- return fonts.map(font => `'${font}'`).join(', ');
-}
-
-const DEFAULT_ACCENT = '#0063B1';
-const DEFAULT_SUBTLE = '#767676'; // With contrast 4.5:1 to white
-const PADDING_REGULAR = 10;
-
-const DEFAULT_OPTIONS = {
- // Color and paddings
- accent: DEFAULT_ACCENT,
- activeActivityOutlineColor: DEFAULT_SUBTLE,
- backgroundColor: 'White',
- cardEmphasisBackgroundColor: '#F0F0F0',
- paddingRegular: PADDING_REGULAR,
- paddingWide: PADDING_REGULAR * 2,
- subtle: DEFAULT_SUBTLE,
-
- // Word break
- messageActivityWordBreak: 'break-word', // 'normal' || 'break-all' || 'break-word' || 'keep-all'
-
- // Fonts
- fontSizeSmall: '80%',
- monospaceFont: fontFamily(['Consolas', 'Courier New', 'monospace']),
- primaryFont: fontFamily(['Calibri', 'Helvetica Neue', 'Arial', 'sans-serif']),
-
- // Avatar
- avatarBorderRadius: '50%',
- avatarSize: 40,
- botAvatarBackgroundColor: undefined, // defaults to accent color
- botAvatarImage: undefined, // Or a string of URL. Can be a data URI or blob.
- botAvatarInitials: undefined, // Or a string. Empty strings means it has avatar but not initials inside.
- userAvatarBackgroundColor: undefined, // defaults to accent color
- userAvatarImage: undefined, // Or a string of URL. Can be a data URI or blob.
- userAvatarInitials: undefined, // Or a string. Empty strings means it has avatar but not initials inside.
- showAvatarInGroup: 'status', // Or 'sender' or true (on every activity).
-
- // Bubble
- // TODO: Should we make a bubbleFromBot*
- bubbleBackground: 'White',
- bubbleBorderColor: '#E6E6E6',
- bubbleBorderRadius: 2,
- bubbleBorderStyle: 'solid',
- bubbleBorderWidth: 1,
- bubbleFromUserBackground: 'White',
- bubbleFromUserBorderColor: '#E6E6E6',
- bubbleFromUserBorderRadius: 2,
- bubbleFromUserBorderStyle: 'solid',
- bubbleFromUserBorderWidth: 1,
- bubbleFromUserNubOffset: 0, // Either a positive/negative number, or "bottom"
- bubbleFromUserNubSize: undefined, // Or a number. 0 means a sharp corner.
- bubbleFromUserTextColor: 'Black',
- bubbleImageHeight: 240,
- bubbleMaxWidth: 480, // screen width = 600px
- bubbleMinHeight: 40,
- bubbleMinWidth: 250, // min screen width = 300px, Microsoft Edge requires 372px (https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/13621468/)
- bubbleNubOffset: 0, // Either a positive/negative number, or "bottom"
- bubbleNubSize: undefined, // Or a number. 0 means a sharp corner.
- bubbleTextColor: 'Black',
-
- // Markdown
- markdownRespectCRLF: true,
-
- // Rich Cards
- richCardWrapTitle: false, // Applies to subtitles as well
-
- // Root
- rootHeight: '100%',
- rootWidth: '100%',
- rootZIndex: 0, // "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.
-
- // Scroll to end button
- hideScrollToEndButton: false,
-
- // Send box
- hideSendBox: false,
- hideUploadButton: false,
- microphoneButtonColorOnDictate: '#F33',
- sendBoxBackground: 'White',
- sendBoxButtonColor: undefined, // defaults to subtle
- sendBoxButtonColorOnDisabled: '#CCC',
- sendBoxButtonColorOnFocus: '#333',
- sendBoxButtonColorOnHover: '#333',
- sendBoxDisabledTextColor: undefined, // defaults to subtle
- sendBoxHeight: 40,
- sendBoxMaxHeight: 200,
- sendBoxTextColor: 'Black',
- // TODO: We should deprecate this because there isn't an easy way to make the width of the send box narrower than the transcript
- sendBoxBorderBottom: '',
- sendBoxBorderLeft: '',
- sendBoxBorderRight: '',
- sendBoxBorderTop: 'solid 1px #E6E6E6',
- sendBoxPlaceholderColor: undefined, // defaults to subtle
- sendBoxTextWrap: false,
- sendBoxButtonAlignment: 'stretch', // "top", "bottom", or "stretch"
-
- // Visually show spoken text
- showSpokenText: false,
-
- // Suggested actions
- suggestedActionBackground: 'White',
- suggestedActionBorder: undefined, // split into 3, null
- suggestedActionBorderColor: undefined, // defaults to accent
- suggestedActionBorderRadius: 0,
- suggestedActionBorderStyle: 'solid',
- suggestedActionBorderWidth: 2,
- suggestedActionDisabledBackground: undefined, // defaults to suggestedActionBackground
- suggestedActionDisabledBorderColor: '#E6E6E6',
- suggestedActionDisabledBorderStyle: 'solid',
- suggestedActionDisabledBorderWidth: 2,
- suggestedActionDisabledTextColor: undefined, // defaults to subtle
- suggestedActionHeight: 40,
- suggestedActionImageHeight: 20,
- suggestedActionLayout: 'carousel', // either 'carousel' or 'stacked'
- suggestedActionTextColor: null,
-
- // Suggested actions carousel layout
- suggestedActionsCarouselFlipperCursor: null, // Cursor when mouse over on flipper
- suggestedActionsCarouselFlipperBoxWidth: 40, // Flipper bounding box size
- suggestedActionsCarouselFlipperSize: 20, // Flipper visible size
-
- // Suggested actions stacked layout
- suggestedActionsStackedHeight: undefined, // sets the container's max height. defaults to 'auto'
- suggestedActionsStackedOverflow: undefined, // defaults to 'auto',
- suggestedActionsStackedLayoutButtonMaxHeight: undefined, // defaults to 100% if suggestedActionsStackedLayoutButtonTextWrap is true
- suggestedActionsStackedLayoutButtonTextWrap: false, // if set to true, buttons with long text will wrap in STACKED mode ONLY
-
- // Timestamp
- groupTimestamp: true,
- sendTimeout: 20000,
- sendTimeoutForAttachments: 120000,
- timestampColor: undefined, // defaults to subtle
- timestampFormat: 'relative', // 'absolute'
-
- // Transcript overlay buttons (e.g. carousel and suggested action flippers, scroll to bottom, etc.)
- newMessagesButtonFontSize: '85%',
- transcriptOverlayButtonBackground: 'rgba(0, 0, 0, .6)',
- transcriptOverlayButtonBackgroundOnFocus: 'rgba(0, 0, 0, .8)',
- transcriptOverlayButtonBackgroundOnHover: 'rgba(0, 0, 0, .8)',
- transcriptOverlayButtonColor: 'White',
- transcriptOverlayButtonColorOnFocus: undefined, // defaults to transcriptOverlayButtonColor
- transcriptOverlayButtonColorOnHover: undefined, // defaults to transcriptOverlayButtonColor
-
- // Video
- videoHeight: 270, // based on bubbleMaxWidth: 480 / 16 * 9 = 270
-
- // Connectivity UI
- connectivityIconPadding: PADDING_REGULAR * 1.2,
- connectivityMarginLeftRight: PADDING_REGULAR * 1.4,
- connectivityMarginTopBottom: PADDING_REGULAR * 0.8,
- connectivityTextSize: '75%',
- failedConnectivity: '#C50F1F',
- slowConnectivity: '#EAA300',
- notificationText: '#5E5E5E',
- slowConnectionAfter: 15000,
-
- typingAnimationBackgroundImage: null,
- typingAnimationDuration: 5000,
- typingAnimationHeight: 20,
- typingAnimationWidth: 64,
-
- spinnerAnimationBackgroundImage: null,
- spinnerAnimationHeight: 16,
- spinnerAnimationWidth: 16,
- spinnerAnimationPadding: 12,
-
- enableUploadThumbnail: true,
- uploadThumbnailContentType: 'image/jpeg',
- uploadThumbnailHeight: 360,
- uploadThumbnailQuality: 0.6,
- uploadThumbnailWidth: 720,
-
- // Toast UI
-
- // New debounce timeout value only affects new notifications.
- notificationDebounceTimeout: 400,
-
- hideToaster: false,
- toasterHeight: 32,
- toasterMaxHeight: 32 * 5,
- toasterSingularMaxHeight: 50,
- toastFontSize: '87.5%',
- toastIconWidth: 36,
- toastSeparatorColor: '#E8EAEC',
- toastTextPadding: 6,
-
- toastErrorBackgroundColor: '#FDE7E9',
- toastErrorColor: '#A80000',
- toastInfoBackgroundColor: '#CEF1FF',
- toastInfoColor: '#105E7D',
- toastSuccessBackgroundColor: '#DFF6DD',
- toastSuccessColor: '#107C10',
- toastWarnBackgroundColor: '#FFF4CE',
- toastWarnColor: '#3B3A39',
-
- // Emoji
- emojiSet: true, // true || false || { ':)' : 'đ'}
-
- // Internal
- internalLiveRegionFadeAfter: 1000,
-
- // Transcript
- transcriptTerminatorBackgroundColor: '#595959',
- transcriptTerminatorBorderRadius: 5,
- transcriptTerminatorColor: 'White',
- transcriptTerminatorFontSize: 12,
-
- transcriptActivityVisualKeyboardIndicatorColor: DEFAULT_SUBTLE,
- transcriptActivityVisualKeyboardIndicatorStyle: 'dashed',
- transcriptActivityVisualKeyboardIndicatorWidth: 1,
-
- transcriptVisualKeyboardIndicatorColor: 'Black',
- transcriptVisualKeyboardIndicatorStyle: 'solid',
- transcriptVisualKeyboardIndicatorWidth: 2,
- //AdaptiveCard push button
- cardPushButtonBackgroundColor: '#0063B1',
- cardPushButtonTextColor: 'white'
-};
-
-export default DEFAULT_OPTIONS;
diff --git a/packages/component/src/index.ts b/packages/component/src/index.ts
new file mode 100644
index 0000000000..d824610b5a
--- /dev/null
+++ b/packages/component/src/index.ts
@@ -0,0 +1,113 @@
+import ReactWebChat from './ReactWebChat';
+
+import Composer from './Composer';
+
+import BasicWebChat from './BasicWebChat';
+
+import Avatar from './Activity/Avatar';
+import Bubble from './Activity/Bubble';
+import ErrorBox from './ErrorBox';
+import SendStatus, { connectSendStatus } from './Middleware/ActivityStatus/SendStatus/SendStatus';
+import SpeakActivity, { connectSpeakActivity } from './Activity/Speak';
+import Timestamp from './Middleware/ActivityStatus/Timestamp';
+
+import AudioContent from './Attachment/AudioContent';
+import FileContent from './Attachment/FileContent';
+import HTMLVideoContent from './Attachment/HTMLVideoContent';
+import ImageContent from './Attachment/ImageContent';
+import TextContent from './Attachment/TextContent';
+import VideoContent from './Attachment/VideoContent';
+import VimeoContent from './Attachment/VimeoContent';
+import YouTubeContent from './Attachment/YouTubeContent';
+
+import DictationInterims, { connectDictationInterims } from './SendBox/DictationInterims';
+import MicrophoneButton, { connectMicrophoneButton } from './SendBox/MicrophoneButton';
+import SendButton, { connectSendButton } from './SendBox/SendButton';
+import SendTextBox, { connectSendTextBox } from './SendBox/TextBox';
+import SuggestedActions, { connectSuggestedActions } from './SendBox/SuggestedActions';
+import UploadButton, { connectUploadButton } from './SendBox/UploadButton';
+
+import connectToWebChat from './connectToWebChat';
+import Context from './hooks/internal/WebChatUIContext';
+import createCoreActivityMiddleware from './Middleware/Activity/createCoreMiddleware';
+import createCoreActivityStatusMiddleware from './Middleware/ActivityStatus/createCoreMiddleware';
+import createCoreAttachmentMiddleware from './Middleware/Attachment/createCoreMiddleware';
+import createStyleSet from './Styles/createStyleSet';
+import getTabIndex from './Utils/TypeFocusSink/getTabIndex';
+
+declare module 'botframework-webchat-api' {
+ export function concatMiddleware(): any;
+ export const hooks: any;
+ export function Localize(): any;
+ export function localize(): any;
+}
+
+import { concatMiddleware, hooks as apiHooks, Localize, localize } from 'botframework-webchat-api';
+import * as componentHooks from './hooks/index';
+
+const hooks = {
+ ...apiHooks,
+ ...componentHooks
+};
+
+// eslint-disable-next-line no-undef
+const version = process.env.npm_package_version;
+
+const Components = {
+ BasicWebChat,
+ Composer,
+ Localize,
+
+ // Components for recomposing activities and attachments
+ AudioContent,
+ FileContent,
+ HTMLVideoContent,
+ ImageContent,
+ TextContent,
+ VideoContent,
+ VimeoContent,
+ YouTubeContent,
+
+ // Components for recomposing transcript
+ Avatar,
+ Bubble,
+ ErrorBox,
+ SendStatus,
+ SpeakActivity,
+ Timestamp,
+
+ connectSendStatus,
+ connectSpeakActivity,
+
+ // Components for recomposing send box
+ DictationInterims,
+ MicrophoneButton,
+ SendButton,
+ SendTextBox,
+ SuggestedActions,
+ UploadButton,
+
+ connectDictationInterims,
+ connectMicrophoneButton,
+ connectSendButton,
+ connectSendTextBox,
+ connectSuggestedActions,
+ connectUploadButton
+};
+
+export default ReactWebChat;
+
+export {
+ Components,
+ concatMiddleware,
+ connectToWebChat,
+ Context,
+ createCoreActivityMiddleware,
+ createCoreActivityStatusMiddleware,
+ createCoreAttachmentMiddleware,
+ createStyleSet,
+ getTabIndex,
+ hooks,
+ localize,
+ version
+};
diff --git a/packages/component/src/index.tsx b/packages/component/src/index.tsx
index 36f4848890..7e7ea124dd 100644
--- a/packages/component/src/index.tsx
+++ b/packages/component/src/index.tsx
@@ -1,107 +1,35 @@
-import ReactWebChat from './ReactWebChat';
+import { FC } from 'react';
+import { StyleOptions } from 'botframework-webchat-api';
-import Composer from './Composer';
+type Expando = Omit & T;
-import BasicWebChat from './BasicWebChat';
+/** Creates a set of styles */
+// eslint-disable-next-line no-unused-vars
+declare function createStyleSet(styleOptions: StyleOptions): any;
-import Avatar from './Activity/Avatar';
-import Bubble from './Activity/Bubble';
-import ErrorBox from './ErrorBox';
-import SendStatus, { connectSendStatus } from './Middleware/ActivityStatus/SendStatus/SendStatus';
-import SpeakActivity, { connectSpeakActivity } from './Activity/Speak';
-import Timestamp from './Middleware/ActivityStatus/Timestamp';
+type ComposerProps = {
+ /** Text directionality */
+ dir?: 'ltr' | 'rtl' | 'auto';
-import AudioContent from './Attachment/AudioContent';
-import FileContent from './Attachment/FileContent';
-import HTMLVideoContent from './Attachment/HTMLVideoContent';
-import ImageContent from './Attachment/ImageContent';
-import TextContent from './Attachment/TextContent';
-import VideoContent from './Attachment/VideoContent';
-import VimeoContent from './Attachment/VimeoContent';
-import YouTubeContent from './Attachment/YouTubeContent';
-
-import DictationInterims, { connectDictationInterims } from './SendBox/DictationInterims';
-import MicrophoneButton, { connectMicrophoneButton } from './SendBox/MicrophoneButton';
-import SendButton, { connectSendButton } from './SendBox/SendButton';
-import SendTextBox, { connectSendTextBox } from './SendBox/TextBox';
-import SuggestedActions, { connectSuggestedActions } from './SendBox/SuggestedActions';
-import UploadButton, { connectUploadButton } from './SendBox/UploadButton';
-
-import connectToWebChat from './connectToWebChat';
-import Context from './hooks/internal/WebChatUIContext';
-import createCoreActivityMiddleware from './Middleware/Activity/createCoreMiddleware';
-import createCoreActivityStatusMiddleware from './Middleware/ActivityStatus/createCoreMiddleware';
-import createCoreAttachmentMiddleware from './Middleware/Attachment/createCoreMiddleware';
-import createStyleSet from './Styles/createStyleSet';
-import defaultStyleOptions from './Styles/defaultStyleOptions';
-import getTabIndex from './Utils/TypeFocusSink/getTabIndex';
-
-import { concatMiddleware, hooks as apiHooks, Localize, localize } from 'botframework-webchat-api';
-import * as componentHooks from './hooks/index';
-
-const hooks = {
- ...apiHooks,
- ...componentHooks
+ /** Style options */
+ styleOptions?: StyleOptions;
};
-const version = process.env.npm_package_version;
-
-const Components = {
- BasicWebChat,
- Composer,
- Localize,
-
- // Components for recomposing activities and attachments
- AudioContent,
- FileContent,
- HTMLVideoContent,
- ImageContent,
- TextContent,
- VideoContent,
- VimeoContent,
- YouTubeContent,
+type ReactWebChatProps = {
+ /** Text directionality */
+ dir?: 'ltr' | 'rtl' | 'auto';
- // Components for recomposing transcript
- Avatar,
- Bubble,
- ErrorBox,
- SendStatus,
- SpeakActivity,
- Timestamp,
-
- connectSendStatus,
- connectSpeakActivity,
+ /** Style options */
+ styleOptions?: StyleOptions;
+};
- // Components for recomposing send box
- DictationInterims,
- MicrophoneButton,
- SendButton,
- SendTextBox,
- SuggestedActions,
- UploadButton,
+/** React-based Web Chat */
+declare const ReactWebChat: FC>;
- connectDictationInterims,
- connectMicrophoneButton,
- connectSendButton,
- connectSendTextBox,
- connectSuggestedActions,
- connectUploadButton
-};
+declare const Components: Expando<{
+ Composer: FC>;
+}>;
export default ReactWebChat;
-
-export {
- Components,
- concatMiddleware,
- connectToWebChat,
- Context,
- createCoreActivityMiddleware,
- createCoreActivityStatusMiddleware,
- createCoreAttachmentMiddleware,
- createStyleSet,
- defaultStyleOptions,
- getTabIndex,
- hooks,
- localize,
- version
-};
+export { Components, createStyleSet };
+export type { ComposerProps, ReactWebChatProps };
diff --git a/packages/component/src/tsconfig.json b/packages/component/src/tsconfig.json
index ca32a35acf..35417e5ca6 100644
--- a/packages/component/src/tsconfig.json
+++ b/packages/component/src/tsconfig.json
@@ -3,11 +3,13 @@
"allowSyntheticDefaultImports": true,
"declaration": true,
"declarationDir": "../lib",
+ "declarationMap": true,
"emitDeclarationOnly": true,
- "isolatedModules": true,
"jsx": "react",
"preserveWatchOutput": true,
"pretty": true,
- "skipLibCheck": true
- }
+ "skipLibCheck": true,
+ "sourceMap": true
+ },
+ "files": ["index.tsx"]
}
diff --git a/packages/core/package-lock.json b/packages/core/package-lock.json
index fc23f08d7e..c5de2befcf 100644
--- a/packages/core/package-lock.json
+++ b/packages/core/package-lock.json
@@ -3521,9 +3521,9 @@
}
},
"semver": {
- "version": "7.3.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
- "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
diff --git a/packages/core/package.json b/packages/core/package.json
index 73b2773c63..0813712bdb 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -33,8 +33,8 @@
"@babel/preset-env": "^7.13.10",
"@babel/preset-typescript": "^7.13.0",
"@types/node": "^14.14.35",
- "@typescript-eslint/eslint-plugin": "^4.18.0",
- "@typescript-eslint/parser": "^4.18.0",
+ "@typescript-eslint/eslint-plugin": "^4.19.0",
+ "@typescript-eslint/parser": "^4.19.0",
"babel-plugin-istanbul": "^6.0.0",
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
"botframework-directlinejs": "^0.14.1",
diff --git a/packages/isomorphic-react-dom/package.json b/packages/isomorphic-react-dom/package.json
index 0808a379bf..ee8730e093 100644
--- a/packages/isomorphic-react-dom/package.json
+++ b/packages/isomorphic-react-dom/package.json
@@ -8,7 +8,6 @@
"build": "npm run build:babel && npm run build:webpack",
"build:babel": "babel src --out-dir lib --verbose",
"build:webpack": "webpack-cli",
- "eslint": "eslint src/**/*.js --fix",
"start": "npm run start:note && npm run start:babel && npm run start:webpack",
"start:babel": "npm run build:babel",
"start:note": "echo \"isomorphic-react-dom is not under active development; running in non-watch mode.\"",
diff --git a/packages/isomorphic-react/package.json b/packages/isomorphic-react/package.json
index 0065b5d1cb..d218d602e3 100644
--- a/packages/isomorphic-react/package.json
+++ b/packages/isomorphic-react/package.json
@@ -7,7 +7,6 @@
"build": "npm run build:babel && npm run build:webpack",
"build:babel": "babel src --out-dir lib --verbose",
"build:webpack": "webpack-cli",
- "eslint": "eslint src/**/*.js --fix",
"start": "npm run start:note && npm run start:babel && npm run start:webpack",
"start:babel": "npm run build:babel",
"start:note": "echo \"isomorphic-react is not under active development; running in non-watch mode.\"",
diff --git a/packages/playground/src/App.js b/packages/playground/src/App.js
index 67b6dee042..c51902ae98 100644
--- a/packages/playground/src/App.js
+++ b/packages/playground/src/App.js
@@ -199,9 +199,9 @@ function App() {
}, [handleUseMockBot]);
// Feel free to change the text to whatever will help you dev faster
- const handleCurrentCommandClick = useCallback(() => {
+ const handleCurrentCommandClick = () => {
store.dispatch({ type: 'WEB_CHAT/SEND_MESSAGE', payload: { text: 'suggested-actions' } });
- });
+ };
/// END CONNECTIVITY
diff --git a/samples/02.branding-styling-and-customization/a.branding-web-chat/README.md b/samples/02.branding-styling-and-customization/a.branding-web-chat/README.md
index 23581c2812..42b535d483 100644
--- a/samples/02.branding-styling-and-customization/a.branding-web-chat/README.md
+++ b/samples/02.branding-styling-and-customization/a.branding-web-chat/README.md
@@ -30,7 +30,7 @@ You may have noticed that Web Chat provides two different ways to change the app
1. 'Branding' your bot via `styleSetOptions` (recommended)
1. Idiosyncratic styling via overriding `createStyleSet` (not recommended)
-`styleSetOptions` is the Web Chat supported method of changing existing DOM elements in the application, and the currently available options are listed on the [`defaultStyleOptions.js` file](https://github.com/microsoft/BotFramework-WebChat/blob/master/packages/component/src/Styles/defaultStyleOptions.js). These options will continue to be updated as we make further as the project grows.
+`styleSetOptions` is the Web Chat supported method of changing existing DOM elements in the application, and the currently available options are listed on the [`defaultStyleOptions.ts` file](https://github.com/microsoft/BotFramework-WebChat/blob/master/packages/api/src/defaultStyleOptions.ts) and [`adaptiveCards/defaultStyleOptions.ts` file](https://github.com/microsoft/BotFramework-WebChat/blob/master/packages/bundle/src/adaptiveCards/defaultStyleOptions.ts) when Adaptive Cards is enabled. These options will continue to be updated as we make further as the project grows.
We provide these options to override for several reasons: