Skip to content

Commit

Permalink
[Fluent theme] Hide buttons, suggested actions FnF and flow layout, D…
Browse files Browse the repository at this point in the history
…TMF FnF (#5132)

* Hide attach file and telephone keypad button

* Touch up

* Smaller suggested actions button

* Fix telephone keypad color contrast

* Sort

* Suggested actions fit-and-finish

* Add entry

* Disable Terrapin

* Fix tests
  • Loading branch information
compulim authored Apr 13, 2024
1 parent ff34969 commit 60fdd80
Show file tree
Hide file tree
Showing 38 changed files with 218 additions and 49 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pull-request-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ env:
CI_PULL_REQUEST: 1 # Skip nightly tests
NODE_ENV: test # Add instrumentation code
node-version: 18.18 # Need to bump jest@29 to resolve something in https://github.com/facebook/react-native/issues/35701
skip-secure-feed: false
skip-secure-feed: true # Terrapin service is degrading and their team told us to disable Terrapin to unblock ourselves

jobs:
build:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- `styleOptions.maxMessageLength` to specify maximum length of the outgoing message
- Drag-and-drop file support, in PR [#5122](https://github.com/microsoft/BotFramework-WebChat/pull/5122)
- Added telephone keypad (DTMF keypad), in PR [#5122](https://github.com/microsoft/BotFramework-WebChat/pull/5122)
- Added support of `styleOptions.hideUploadButton`, in PR [#5132](https://github.com/microsoft/BotFramework-WebChat/pull/5132)
- Added `styleOptions.hideTelephoneKeypadButton` and default to `true`, in PR [#5132](https://github.com/microsoft/BotFramework-WebChat/pull/5132)
- Fit-and-finish on suggested actions and telephone keypad, in PR [#5132](https://github.com/microsoft/BotFramework-WebChat/pull/5132)
- Fixed to keep telephone keypad on-screen on click, in PR [#5132](https://github.com/microsoft/BotFramework-WebChat/pull/5132)
- Added `<ThemeProvider>` component to apply theme pack to Web Chat, by [@compulim](https://github.com/compulim), in PR [#5120](https://github.com/microsoft/BotFramework-WebChat/pull/5120)
- Added `useMakeThumbnail` hook option to create a thumbnail from the file given, by [@compulim](https://github.com/compulim), in PR [#5123](https://github.com/microsoft/BotFramework-WebChat/pull/5123) and [#5122](https://github.com/microsoft/BotFramework-WebChat/pull/5122)

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions __tests__/html/fluentTheme/hideAttachFileButton.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!doctype html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<script crossorigin="anonymous" src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
<script crossorigin="anonymous" src="/test-harness.js"></script>
<script crossorigin="anonymous" src="/test-page-object.js"></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
<script crossorigin="anonymous" src="/__dist__/botframework-webchat-fluent-theme.production.min.js"></script>
</head>
<body>
<main id="webchat"></main>
<script type="text/babel">
run(async function () {
const {
React,
ReactDOM: { render },
WebChat: { FluentThemeProvider, ReactWebChat }
} = window; // Imports in UMD fashion.

const { directLine, store } = testHelpers.createDirectLineEmulator();

const App = () => (
<ReactWebChat directLine={directLine} store={store} styleOptions={{ hideUploadButton: true }} />
);

render(
<FluentThemeProvider>
<App />
</FluentThemeProvider>,
document.getElementById('webchat')
);

await pageConditions.uiConnected();

// THEN: No attach button should be render.
expect(pageElements.byTestId(WebChat.testIds.sendBoxUploadButton)).toBeFalsy();
await host.snapshot();
});
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions __tests__/html/fluentTheme/hideAttachFileButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('Fluent theme applied', () => {
test('when styleOptions.hideUploadButton is truthy should not render attach file button', () => runHTML('fluentTheme/hideAttachFileButton'));
});
80 changes: 80 additions & 0 deletions __tests__/html/fluentTheme/suggestedActions.layout.flow.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<!doctype html>
<html lang="en-US">
<head>
<link href="/assets/index.css" rel="stylesheet" type="text/css" />
<script crossorigin="anonymous" src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script crossorigin="anonymous" src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
<script crossorigin="anonymous" src="/test-harness.js"></script>
<script crossorigin="anonymous" src="/test-page-object.js"></script>
<script crossorigin="anonymous" src="/__dist__/webchat-es5.js"></script>
<script crossorigin="anonymous" src="/__dist__/botframework-webchat-fluent-theme.production.min.js"></script>
</head>
<body>
<main id="webchat"></main>
<script type="text/babel">
run(async function () {
const {
React,
ReactDOM: { render },
WebChat: { FluentThemeProvider, ReactWebChat }
} = window; // Imports in UMD fashion.

const { directLine, store } = testHelpers.createDirectLineEmulator();

const App = () => (
<ReactWebChat directLine={directLine} store={store} styleOptions={{ suggestedActionLayout: 'flow' }} />
);

render(
<FluentThemeProvider>
<App />
</FluentThemeProvider>,
document.getElementById('webchat')
);

await pageConditions.uiConnected();

await directLine.emulateIncomingActivity({
type: 'message',
textFormat: 'plain',
text: 'Please select one of the actions below',
suggestedActions: {
actions: [
{ title: 'A', type: 'imBack' },
{ title: 'B', type: 'imBack' },
{ title: 'C', type: 'imBack' },
{ title: 'D', type: 'imBack' },
{ title: 'E', type: 'imBack' },
{ title: 'F', type: 'imBack' },
{ title: 'G', type: 'imBack' },
{ title: 'H', type: 'imBack' },
{ title: 'I', type: 'imBack' },
{ title: 'J', type: 'imBack' },
{ title: 'K', type: 'imBack' },
{ title: 'L', type: 'imBack' },
{ title: 'M', type: 'imBack' },
{ title: 'N', type: 'imBack' },
{ title: 'O', type: 'imBack' },
{ title: 'P', type: 'imBack' },
{ title: 'Q', type: 'imBack' },
{ title: 'R', type: 'imBack' },
{ title: 'S', type: 'imBack' },
{ title: 'T', type: 'imBack' },
{ title: 'U', type: 'imBack' },
{ title: 'V', type: 'imBack' },
{ title: 'W', type: 'imBack' },
{ title: 'X', type: 'imBack' },
{ title: 'Y', type: 'imBack' },
{ title: 'Z', type: 'imBack' }
],
to: []
}
});

// THEN: Should render the activity.
await host.snapshot();
});
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions __tests__/html/fluentTheme/suggestedActions.layout.flow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @jest-environment ./packages/test/harness/src/host/jest/WebDriverEnvironment.js */

describe('Fluent theme applied', () => {
test('renders suggested actions with a flow layout', () => runHTML('fluentTheme/suggestedActions.layout.flow'));
});
4 changes: 3 additions & 1 deletion __tests__/html/fluentTheme/tabOrder.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

const { directLine, store } = testHelpers.createDirectLineEmulator();

const App = () => <ReactWebChat directLine={directLine} store={store} />;
const App = () => (
<ReactWebChat directLine={directLine} store={store} styleOptions={{ hideTelephoneKeypadButton: false }} />
);

render(
<FluentThemeProvider>
Expand Down
4 changes: 3 additions & 1 deletion __tests__/html/fluentTheme/telephoneKeypad.showHide.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

const { directLine, store } = testHelpers.createDirectLineEmulator();

const App = () => <ReactWebChat directLine={directLine} store={store} />;
const App = () => (
<ReactWebChat directLine={directLine} store={store} styleOptions={{ hideTelephoneKeypadButton: false }} />
);

render(
<FluentThemeProvider>
Expand Down
19 changes: 9 additions & 10 deletions __tests__/html/fluentTheme/telephoneKeypad.tap.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

const { directLine, store } = testHelpers.createDirectLineEmulator();

const App = () => <ReactWebChat directLine={directLine} store={store} />;
const App = () => (
<ReactWebChat directLine={directLine} store={store} styleOptions={{ hideTelephoneKeypadButton: false }} />
);

render(
<FluentThemeProvider>
Expand All @@ -40,24 +42,21 @@
await pageConditions.numActivitiesShown(1);

// WHEN: Telephone keypad button is clicked.
await host.click(
document.querySelector(`[data-testid="${WebChat.testIds.sendBoxTelephoneKeypadToolbarButton}"]`)
);
await host.click(pageElements.byTestId(WebChat.testIds.sendBoxTelephoneKeypadToolbarButton));

await (
await directLine.actPostActivity(() =>
host.click(document.querySelector(`[data-testid="${WebChat.testIds.sendBoxTelephoneKeypadButton5}"]`))
host.click(pageElements.byTestId(WebChat.testIds.sendBoxTelephoneKeypadButton5))
)
).resolveAll();

// THEN: Should send "/DTMF 5" and focus on the send box.
// THEN: Should send "/DTMF 5".
await pageConditions.numActivitiesShown(2);
expect(pageElements.activityContents()[1]).toHaveProperty('textContent', '/DTMF 5');

// Commented out because it is not working today.
// expect(document.activeElement).toBe(
// document.querySelector(`[data-testid="${WebChat.testIds.sendBoxTextBox}"]`)
// );
// THEN: Should not close the keypad and keep focusing on the button "5".
expect(pageElements.byTestId(WebChat.testIds.sendBoxTelephoneKeypadButton5)).toBeTruthy();
expect(document.activeElement).toBe(pageElements.byTestId(WebChat.testIds.sendBoxTelephoneKeypadButton5));

await host.snapshot();
});
Expand Down
8 changes: 8 additions & 0 deletions packages/api/src/StyleOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,14 @@ type StyleOptions = {

hideSendBox?: boolean;
hideUploadButton?: boolean;

/**
* (EXPERIMENTAL) `true`, if the telephone keypad button should be shown, otherwise, `false`. Defaults to `true`.
*
* @deprecated This is an experimental style options and should not be used without understanding its risk.
*/
hideTelephoneKeypadButton?: boolean | undefined;

microphoneButtonColorOnDictate?: string;
sendBoxBackground?: string;

Expand Down
1 change: 1 addition & 0 deletions packages/api/src/defaultStyleOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ const DEFAULT_OPTIONS: Required<StyleOptions> = {
// Send box
hideSendBox: false,
hideUploadButton: false,
hideTelephoneKeypadButton: true,
microphoneButtonColorOnDictate: '#F33',
sendBoxBackground: 'White',
uploadAccept: undefined,
Expand Down
3 changes: 2 additions & 1 deletion packages/fluent-theme/src/components/Theme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ const styles = {

'--webchat-colorStatusDangerForeground1': 'var(--colorStatusDangerForeground1, #b10e1c)',

// https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/colors.ts
// https://github.com/microsoft/fluentui/blob/master/packages/theme/src/colors/FluentColors.ts
'--webchat-colorGray30': 'var(--colorGray30, #edebe9)',
'--webchat-colorGray160': 'var(--colorGray160, #323130)',
'--webchat-colorGray190': 'var(--colorGray190, #201f1e)',
'--webchat-colorGray200': 'var(--colorGray200, #1b1a19)',

// https://github.com/microsoft/fluentui/blob/master/packages/tokens/src/global/borderRadius.ts
Expand Down
2 changes: 1 addition & 1 deletion packages/fluent-theme/src/components/sendbox/TextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const styles = {
},

'&::-webkit-scrollbar-track': {
backgroundColor: ' var(--webchat-colorNeutralBackground5)',
backgroundColor: 'var(--webchat-colorNeutralBackground5)',
borderRadius: '16px'
},

Expand Down
2 changes: 1 addition & 1 deletion packages/fluent-theme/src/components/sendbox/Toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const styles = {
color: 'var(--webchat-colorCompoundBrandForeground1Pressed)'
},
'&[aria-disabled="true"]': {
color: ' var(--webchat-colorNeutralForegroundDisabled)',
color: 'var(--webchat-colorNeutralForegroundDisabled)',
cursor: 'not-allowed'
}
},
Expand Down
19 changes: 7 additions & 12 deletions packages/fluent-theme/src/components/sendbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,15 @@ function SendBox(
const inputRef = useRef<HTMLTextAreaElement>(null);
const [message, setMessage] = useState('');
const [attachments, setAttachments] = useSendBoxAttachments();
const [{ maxMessageLength }] = useStyleOptions();
const [{ hideTelephoneKeypadButton, hideUploadButton, maxMessageLength }] = useStyleOptions();
const isMessageLengthExceeded = !!maxMessageLength && message.length > maxMessageLength;
const classNames = useStyles(styles);
const localize = useLocalizer();
const sendMessage = useSendMessage();
const makeThumbnail = useMakeThumbnail();
const errorMessageId = useUniqueId('webchat-fluent__sendbox__error-message-id');
const [errorRef, errorMessage] = useSubmitError({ message, attachments });
const [telephoneKeypadShown, setTelephoneKeypadShown] = useTelephoneKeypadShown();
const [telephoneKeypadShown] = useTelephoneKeypadShown();

const attachmentsRef = useRefFrom(attachments);
const messageRef = useRefFrom(message);
Expand Down Expand Up @@ -162,14 +162,9 @@ function SendBox(
);

const handleTelephoneKeypadButtonClick = useCallback(
(dtmf: DTMF) => {
// TODO: We need more official way of sending DTMF.
sendMessage(`/DTMF ${dtmf}`);

// TODO: In the future when we work on input modality, it should manage the focus in a better way.
setTelephoneKeypadShown(false);
},
[sendMessage, setTelephoneKeypadShown]
// TODO: We need more official way of sending DTMF.
(dtmf: DTMF) => sendMessage(`/DTMF ${dtmf}`),
[sendMessage]
);

const aria = {
Expand Down Expand Up @@ -211,8 +206,8 @@ function SendBox(
</div>
)}
<Toolbar>
<TelephoneKeypadToolbarButton />
<AddAttachmentButton onFilesAdded={handleAddFiles} />
{!hideTelephoneKeypadButton && <TelephoneKeypadToolbarButton />}
{!hideUploadButton && <AddAttachmentButton onFilesAdded={handleAddFiles} />}
<ToolbarSeparator />
<ToolbarButton
aria-label={localize('TEXT_INPUT_SEND_BUTTON_ALT')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { hooks } from 'botframework-webchat-component';
import { type DirectLineCardAction } from 'botframework-webchat-core';
import cx from 'classnames';
import React, { MouseEventHandler, memo, useCallback, useRef } from 'react';
import AccessibleButton from './AccessibleButton';
import { useStyles } from '../../styles';
import AccessibleButton from './AccessibleButton';

const { useScrollToEnd, useStyleSet, usePerformCardAction, useFocus, useSuggestedActions, useDisabled } = hooks;
const { useDisabled, useFocus, usePerformCardAction, useScrollToEnd, useStyleSet, useSuggestedActions } = hooks;

type SuggestedActionProps = Readonly<{
buttonText: string | undefined;
Expand All @@ -31,17 +31,16 @@ type SuggestedActionProps = Readonly<{

const styles = {
'webchat-fluent__suggested-action': {
alignItems: 'center',
background: 'transparent',
border: '1px solid var(--webchat-colorBrandStroke2)',
borderRadius: '8px',
cursor: 'pointer',
fontSize: '12px',
lineHeight: '14px',
padding: '6px 8px 4px',
textAlign: 'start',
display: 'flex',
fontSize: '12px',
gap: '4px',
alignItems: 'center',
padding: '4px 8px 4px',
textAlign: 'start',
transition: 'all .15s ease-out',

'@media (hover: hover)': {
Expand All @@ -50,21 +49,20 @@ const styles = {
color: 'var(--webchat-colorBrandForeground2Hover)'
}
},

'&:not([aria-disabled="true"]):active': {
backgroundColor: 'var(--webchat-colorBrandBackground2Pressed)',
color: 'var(--webchat-colorBrandForeground2Pressed)'
},

'&[aria-disabled="true"]': {
color: ' var(--webchat-colorNeutralForegroundDisabled)',
color: 'var(--webchat-colorNeutralForegroundDisabled)',
cursor: 'not-allowed'
}
},

'webchat-fluent__suggested-action__image': {
width: '1em',
height: '1em',
fontSize: '20px',
translate: '0 -1px'
height: '12px'
}
};

Expand Down
Loading

0 comments on commit 60fdd80

Please sign in to comment.