@microsoft/omnichannel-chat-components 1.1.19 → 1.2.0-main.7c4503c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -1
- package/lib/cjs/common/Constants.js +8 -11
- package/lib/cjs/components/callingcontainer/subcomponents/CurrentCall/CurrentCall.js +10 -3
- package/lib/cjs/components/callingcontainer/subcomponents/Timer/Timer.js +10 -1
- package/lib/cjs/components/chatbutton/ChatButton.blankAnnouncements.a11y.spec.js +158 -0
- package/lib/cjs/components/chatbutton/ChatButton.browseMode.a11y.spec.js +227 -0
- package/lib/cjs/components/chatbutton/ChatButton.browseMode.unfixed.a11y.spec.js +112 -0
- package/lib/cjs/components/chatbutton/ChatButton.js +52 -16
- package/lib/cjs/components/common/subcomponents/CloseButton.js +1 -3
- package/lib/cjs/components/confirmationpane/ConfirmationPane.js +10 -8
- package/lib/cjs/components/confirmationpane/common/defaultProps/defaultConfirmationPaneControlProps.js +1 -0
- package/lib/cjs/components/footer/subcomponents/AudioNotificationButton.js +11 -4
- package/lib/cjs/components/footer/subcomponents/DownloadTranscriptButton.js +1 -3
- package/lib/cjs/components/footer/subcomponents/EmailTranscriptButton.js +1 -3
- package/lib/cjs/components/header/Header.js +16 -4
- package/lib/cjs/components/header/common/defaultStyles/defaultHeaderStyleProps.js +23 -0
- package/lib/cjs/components/header/subcomponents/MinimizeButton.js +1 -3
- package/lib/cjs/components/inputvalidationpane/InputValidationPane.js +34 -14
- package/lib/cjs/components/inputvalidationpane/common/default/defaultProps/defaultInputValidationPaneControlProps.js +1 -0
- package/lib/cjs/components/notificationpane/subcomponents/CloseChatButton.js +1 -3
- package/lib/cjs/components/notificationpane/subcomponents/DismissButton.js +1 -3
- package/lib/cjs/components/prechatsurveypane/PreChatSurveyPane.js +94 -17
- package/lib/cjs/components/prechatsurveypane/common/defaultProps/defaultStyles/defaultPreChatSurveyPaneMultichoiceInputStyles.js +1 -0
- package/lib/cjs/components/prechatsurveypane/common/defaultProps/defaultStyles/defaultPreChatSurveyPaneMultilineTextInputStyles.js +1 -0
- package/lib/cjs/components/prechatsurveypane/common/defaultProps/defaultStyles/defaultPreChatSurveyPaneTextInputStyles.js +1 -0
- package/lib/cjs/package.json +1 -0
- package/lib/cjs/services/EventQueue.js +4 -7
- package/lib/esm/common/Constants.js +1 -1
- package/lib/esm/components/callingcontainer/subcomponents/CurrentCall/CurrentCall.js +10 -3
- package/lib/esm/components/callingcontainer/subcomponents/Timer/Timer.js +10 -1
- package/lib/esm/components/chatbutton/ChatButton.blankAnnouncements.a11y.spec.js +155 -0
- package/lib/esm/components/chatbutton/ChatButton.browseMode.a11y.spec.js +224 -0
- package/lib/esm/components/chatbutton/ChatButton.browseMode.unfixed.a11y.spec.js +108 -0
- package/lib/esm/components/chatbutton/ChatButton.js +53 -16
- package/lib/esm/components/common/subcomponents/CloseButton.js +1 -3
- package/lib/esm/components/confirmationpane/ConfirmationPane.js +10 -8
- package/lib/esm/components/confirmationpane/common/defaultProps/defaultConfirmationPaneControlProps.js +1 -0
- package/lib/esm/components/footer/subcomponents/AudioNotificationButton.js +11 -4
- package/lib/esm/components/footer/subcomponents/DownloadTranscriptButton.js +1 -3
- package/lib/esm/components/footer/subcomponents/EmailTranscriptButton.js +1 -3
- package/lib/esm/components/header/Header.js +16 -4
- package/lib/esm/components/header/common/defaultStyles/defaultHeaderStyleProps.js +23 -0
- package/lib/esm/components/header/subcomponents/MinimizeButton.js +1 -3
- package/lib/esm/components/inputvalidationpane/InputValidationPane.js +34 -14
- package/lib/esm/components/inputvalidationpane/common/default/defaultProps/defaultInputValidationPaneControlProps.js +1 -0
- package/lib/esm/components/notificationpane/subcomponents/CloseChatButton.js +1 -3
- package/lib/esm/components/notificationpane/subcomponents/DismissButton.js +1 -3
- package/lib/esm/components/prechatsurveypane/PreChatSurveyPane.js +94 -16
- package/lib/esm/components/prechatsurveypane/common/defaultProps/defaultStyles/defaultPreChatSurveyPaneMultichoiceInputStyles.js +1 -0
- package/lib/esm/components/prechatsurveypane/common/defaultProps/defaultStyles/defaultPreChatSurveyPaneMultilineTextInputStyles.js +1 -0
- package/lib/esm/components/prechatsurveypane/common/defaultProps/defaultStyles/defaultPreChatSurveyPaneTextInputStyles.js +1 -0
- package/lib/types/common/Constants.d.ts +2 -0
- package/lib/types/components/chatbutton/ChatButton.blankAnnouncements.a11y.spec.d.ts +1 -0
- package/lib/types/components/chatbutton/ChatButton.browseMode.a11y.spec.d.ts +1 -0
- package/lib/types/components/chatbutton/ChatButton.browseMode.unfixed.a11y.spec.d.ts +1 -0
- package/lib/types/components/confirmationpane/interfaces/IConfirmationPaneControlProps.d.ts +1 -0
- package/lib/types/components/header/interfaces/IHeaderStyleProps.d.ts +12 -0
- package/lib/types/components/inputvalidationpane/interfaces/IInputValidationPaneControlProps.d.ts +1 -0
- package/package.json +39 -31
package/README.md
CHANGED
|
@@ -1 +1,140 @@
|
|
|
1
|
-
|
|
1
|
+
# Microsoft Omnichannel Chat Components
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@microsoft/omnichannel-chat-components)
|
|
4
|
+
[](https://www.npmjs.com/package/@microsoft/omnichannel-chat-components)
|
|
5
|
+
[](https://github.com/microsoft/omnichannel-chat-widget/actions/workflows/npm-release.yml)
|
|
6
|
+
|
|
7
|
+
`@microsoft/omnichannel-chat-components` provides the stateless React controls for a Dynamics 365 customer chat experience.
|
|
8
|
+
|
|
9
|
+
Use this package when your application owns the chat state and needs the Microsoft user interface controls.
|
|
10
|
+
|
|
11
|
+
Use [`@microsoft/omnichannel-chat-widget`](https://www.npmjs.com/package/@microsoft/omnichannel-chat-widget) for an integrated widget that connects these controls to the Chat SDK.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
This release builds and tests with React 18. Install React and ReactDOM in the application.
|
|
16
|
+
|
|
17
|
+
For a production application, pin the exact stable package version:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install --save-exact @microsoft/omnichannel-chat-components@1.2.0 react@18 react-dom@18
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
You can also use Yarn:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
yarn add --exact @microsoft/omnichannel-chat-components@1.2.0 react@18 react-dom@18
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The package installs Fluent UI version 8 and its other runtime dependencies.
|
|
30
|
+
|
|
31
|
+
## Basic use
|
|
32
|
+
|
|
33
|
+
Initialize the broadcast service one time before you render controls that publish events.
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import * as React from "react";
|
|
37
|
+
import { createRoot } from "react-dom/client";
|
|
38
|
+
import {
|
|
39
|
+
BroadcastServiceInitialize,
|
|
40
|
+
ChatButton
|
|
41
|
+
} from "@microsoft/omnichannel-chat-components";
|
|
42
|
+
|
|
43
|
+
BroadcastServiceInitialize("customer-chat");
|
|
44
|
+
|
|
45
|
+
function App(): React.ReactElement {
|
|
46
|
+
return (
|
|
47
|
+
<ChatButton
|
|
48
|
+
controlProps={{
|
|
49
|
+
ariaLabel: "Start a chat",
|
|
50
|
+
titleText: "Chat with us",
|
|
51
|
+
subtitleText: "We are online",
|
|
52
|
+
onClick: () => {
|
|
53
|
+
console.log("Start the chat");
|
|
54
|
+
}
|
|
55
|
+
}}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
createRoot(document.getElementById("root")!).render(<App />);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The controls do not start or manage a chat session. Connect their callbacks and broadcast events to your application state.
|
|
64
|
+
|
|
65
|
+
## Exported API
|
|
66
|
+
|
|
67
|
+
The package exports these control groups:
|
|
68
|
+
|
|
69
|
+
| Group | Exports |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| Chat shell | `Header`, `Footer`, `ChatButton`, `NotificationPane` |
|
|
72
|
+
| Status and forms | `ConfirmationPane`, `InputValidationPane`, `LoadingPane`, `OutOfOfficeHoursPane` |
|
|
73
|
+
| Surveys and proactive chat | `PreChatSurveyPane`, `PostChatSurveyPane`, `ProactiveChatPane`, `ReconnectChatPane` |
|
|
74
|
+
| Calling | `CallingContainer`, `CurrentCall`, `IncomingCall`, `Timer` |
|
|
75
|
+
| Services and utilities | `BroadcastService`, `BroadcastServiceInitialize`, `ElementType`, `encodeComponentString`, `decodeComponentString` |
|
|
76
|
+
| Assets | The package exports the default chat, calling, notification, transcript, and status icons. |
|
|
77
|
+
|
|
78
|
+
Read the [component guide](https://github.com/microsoft/omnichannel-chat-widget/blob/main/docs/customizations/getstarted.md) for control properties and style examples.
|
|
79
|
+
|
|
80
|
+
The root [component table](https://github.com/microsoft/omnichannel-chat-widget#stateless-ui-components) links each control to its TypeScript interface.
|
|
81
|
+
|
|
82
|
+
Run Storybook locally to examine the available states:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
yarn install --frozen-lockfile
|
|
86
|
+
yarn storybook
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Package formats
|
|
90
|
+
|
|
91
|
+
The npm package contains these outputs:
|
|
92
|
+
|
|
93
|
+
| Consumer | Entry |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| ECMAScript modules | `lib/esm/index.js` |
|
|
96
|
+
| CommonJS | `lib/cjs/index.js` |
|
|
97
|
+
| TypeScript declarations | `lib/types/index.d.ts` |
|
|
98
|
+
|
|
99
|
+
Use the package root import. The `exports` map selects the correct JavaScript entry.
|
|
100
|
+
|
|
101
|
+
## Accessibility
|
|
102
|
+
|
|
103
|
+
The controls use semantic HTML, ARIA attributes, focus management, and screen-reader announcements.
|
|
104
|
+
|
|
105
|
+
The repository includes unit, visual, axe, and Microsoft Accessibility Insights coverage. Automated scans do not replace manual assistive-technology tests.
|
|
106
|
+
|
|
107
|
+
## Development
|
|
108
|
+
|
|
109
|
+
The repository uses the Node.js version in [`.nvmrc`](https://github.com/microsoft/omnichannel-chat-widget/blob/main/.nvmrc) and Yarn 1.
|
|
110
|
+
|
|
111
|
+
Run these commands from `chat-components`:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
yarn install --frozen-lockfile
|
|
115
|
+
yarn build
|
|
116
|
+
yarn test:unit
|
|
117
|
+
yarn test:cjs
|
|
118
|
+
yarn build-storybook
|
|
119
|
+
yarn test:visual --forceExit
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Releases
|
|
123
|
+
|
|
124
|
+
- Read the [Chat Components changelog](https://github.com/microsoft/omnichannel-chat-widget/blob/main/CHANGE_LOG.md#chat-components).
|
|
125
|
+
- Read the [official release procedure](https://github.com/microsoft/omnichannel-chat-widget/blob/main/docs/RELEASING.md).
|
|
126
|
+
- Find published packages on [npm](https://www.npmjs.com/package/@microsoft/omnichannel-chat-components).
|
|
127
|
+
- Find official tags and release assets on [GitHub Releases](https://github.com/microsoft/omnichannel-chat-widget/releases).
|
|
128
|
+
|
|
129
|
+
Official Chat Components tags use `c-v<version>`. Starting with `c-v1.2.0`, each tag publishes the same tarball to npm and GitHub.
|
|
130
|
+
|
|
131
|
+
`1.2.0` was released on 2026-08-18. Official support ends on 2027-08-18. See the [root support table](https://github.com/microsoft/omnichannel-chat-widget#chat-components).
|
|
132
|
+
|
|
133
|
+
## Support and security
|
|
134
|
+
|
|
135
|
+
- Use [GitHub Issues](https://github.com/microsoft/omnichannel-chat-widget/issues) for reproducible product defects.
|
|
136
|
+
- Read [SUPPORT.md](https://github.com/microsoft/omnichannel-chat-widget/blob/main/SUPPORT.md) before you request product help.
|
|
137
|
+
- Report vulnerabilities through [SECURITY.md](https://github.com/microsoft/omnichannel-chat-widget/blob/main/SECURITY.md).
|
|
138
|
+
- Obey the [Microsoft Open Source Code of Conduct](https://github.com/microsoft/omnichannel-chat-widget/blob/main/CODE_OF_CONDUCT.md).
|
|
139
|
+
|
|
140
|
+
This project uses the [MIT License](https://github.com/microsoft/omnichannel-chat-widget/blob/main/LICENSE).
|
|
@@ -5,9 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.Texts = exports.Regex = exports.KeyCodes = exports.Ids = exports.IconNames = exports.HiddenTextStyles = exports.EventNames = exports.ElementType = exports.ButtonTypes = exports.AriaLabels = exports.AccessibilityBrightnessRatio = void 0;
|
|
7
7
|
var _Class, _Class2, _Class3, _Class4, _Class5, _Class6, _Class7, _Class8;
|
|
8
|
-
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
9
|
-
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
10
|
-
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
11
8
|
/* CSS Constants */
|
|
12
9
|
const AccessibilityBrightnessRatio = exports.AccessibilityBrightnessRatio = 1.2;
|
|
13
10
|
const HiddenTextStyles = exports.HiddenTextStyles = {
|
|
@@ -18,8 +15,8 @@ const HiddenTextStyles = exports.HiddenTextStyles = {
|
|
|
18
15
|
clip: "rect(1px, 1px, 1px, 1px)",
|
|
19
16
|
whiteSpace: "nowrap"
|
|
20
17
|
};
|
|
21
|
-
const KeyCodes = exports.KeyCodes = (_Class = class KeyCodes {},
|
|
22
|
-
const Regex = exports.Regex = (_Class2 = class Regex {},
|
|
18
|
+
const KeyCodes = exports.KeyCodes = (_Class = class KeyCodes {}, _Class.ENTER = "Enter", _Class.ESCAPE = "Escape", _Class.SPACE = "Space", _Class.DeclineCallHotKey = "D", _Class.AcceptAudioCallHotKey = "S", _Class.AcceptVideoCallHotKey = "A", _Class.ToggleMicHotKey = "M", _Class.ToggleCameraHotKey = "O", _Class.EndCallHotKey = "H", _Class);
|
|
19
|
+
const Regex = exports.Regex = (_Class2 = class Regex {}, _Class2.EmailRegex = "(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])", _Class2.URLRegex = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,}|mailto:[^\s]+|tel:[^\s]+|sms:[^\s]+)/gi, _Class2);
|
|
23
20
|
let ElementType = exports.ElementType = /*#__PURE__*/function (ElementType) {
|
|
24
21
|
ElementType["ChatButton"] = "ChatButton";
|
|
25
22
|
ElementType["CloseButton"] = "CloseButton";
|
|
@@ -47,9 +44,9 @@ let ElementType = exports.ElementType = /*#__PURE__*/function (ElementType) {
|
|
|
47
44
|
ElementType["Custom"] = "Custom";
|
|
48
45
|
return ElementType;
|
|
49
46
|
}({});
|
|
50
|
-
const Ids = exports.Ids = (_Class3 = class Ids {},
|
|
51
|
-
const ButtonTypes = exports.ButtonTypes = (_Class4 = class ButtonTypes {},
|
|
52
|
-
const IconNames = exports.IconNames = (_Class5 = class IconNames {},
|
|
53
|
-
const AriaLabels = exports.AriaLabels = (_Class6 = class AriaLabels {},
|
|
54
|
-
const EventNames = exports.EventNames = (_Class7 = class EventNames {},
|
|
55
|
-
const Texts = exports.Texts = (_Class8 = class Texts {},
|
|
47
|
+
const Ids = exports.Ids = (_Class3 = class Ids {}, _Class3.DefaultCallingContainerId = "lcw-calling-container", _Class3.DefaultCurrentCallId = "lcw-current-call-container", _Class3.CurrentCallActionGroupId = "lcw-current-call-action-icons", _Class3.CurrentCallFooterId = "lcw-current-call-footer", _Class3.RemoteVideoTileId = "lcw-remote-video", _Class3.SelfVideoTileId = "lcw-self-video", _Class3.VideoTileGroupId = "lcw-current-call-body", _Class3.EndCallButtonId = "lcw-call-reject-button", _Class3.MicButtonId = "lcw-toggle-audio", _Class3.VideoButtonId = "lcw-toggle-video", _Class3.CallTimerId = "lcw-current-call-timer", _Class3.CurrentCallLeftGroupId = "lcw-current-call-left-group", _Class3.CurrentCallMiddleGroupId = "lcw-current-call-middle-group", _Class3.CurrentCallRightGroupId = "lcw-current-call-right-group", _Class3.DefaultIncomingCallId = "lcw-incoming-call", _Class3.DeclineCallButtonId = "lcw-call-reject-button", _Class3.AudioCallButtonId = "lcw-call-accept-button", _Class3.VideoCallButtonId = "lcw-video-call-accept-button", _Class3.IncomingCallTitleId = "lcw-incoming-call-message", _Class3.DefaultIncomingCallPopupId = "lcw-incoming-call-popup", _Class3.IncomingCallLeftGroupId = "lcw-incoming-call-left-group", _Class3.IncomingCallMiddleGroupId = "lcw-incoming-call-middle-group", _Class3.IncomingCallRightGroupId = "lcw-incoming-call-right-group", _Class3.DefaultChatButtonId = "lcw-components-chat-button", _Class3.DefaultConfirmationPaneId = "lcw-components-confirmation-pane", _Class3.CustomFooterId = "lcw-footer", _Class3.DownloadTranscriptButtonId = "lcw-footer-download-transcript-button", _Class3.EmailTranscriptButtonId = "lcw-footer-email-transcript-button", _Class3.AudioNotificationButtonId = "lcw-footer-audio-notification-button", _Class3.DefaultFooterId = "lcw-components-footer", _Class3.FooterLeftGroupId = "lcw-footer-left-group", _Class3.FooterMiddleGroupId = "lcw-footer-middle-group", _Class3.FooterRightGroupId = "lcw-footer-right-group", _Class3.DefaultHeaderId = "lcw-header", _Class3.MinimizeButtonId = "lcw-header-minimize-button", _Class3.CloseButtonId = "lcw-header-close-button", _Class3.HeaderIconId = "lcw-header-icon", _Class3.HeaderTitleId = "lcw-header-title", _Class3.HeaderLeftGroupId = "lcw-header-left-group", _Class3.HeaderMiddleGroupId = "lcw-header-middle-group", _Class3.HeaderRightGroupId = "lcw-header-right-group", _Class3.DefaultInputValidationPaneId = "lcw-email-transcript-dialog-container", _Class3.DefaultInputValidationPaneInputId = "lcw-email-transcript-dialog-text-field", _Class3.DefaultLoadingPaneId = "lcw-loading-pane", _Class3.DefaultNotificationPaneId = "lcw-notification-pane", _Class3.DefaultOOOHPaneId = "lcw-out-of-office-hours-pane", _Class3.DefaultPostChatSurveyPaneId = "lcw-postchat-survey-pane", _Class3.DefaultPreChatSurveyPaneId = "lcw-prechat-survey-pane-default", _Class3.DefaultProactiveChatPaneId = "lcw-proactive-chat", _Class3.DefaultReconnectChatPaneId = "lcw-reconnect-chat-pane", _Class3);
|
|
48
|
+
const ButtonTypes = exports.ButtonTypes = (_Class4 = class ButtonTypes {}, _Class4.Icon = "icon", _Class4.Text = "text", _Class4);
|
|
49
|
+
const IconNames = exports.IconNames = (_Class5 = class IconNames {}, _Class5.DeclineCall = "DeclineCall", _Class5.Microphone = "Microphone", _Class5.MicOff2 = "MicOff2", _Class5.Video = "Video", _Class5.VideoOff = "VideoOff", _Class5.IncomingCall = "IncomingCall", _Class5.ChromeClose = "ChromeClose", _Class5.Download = "Download", _Class5.Mail = "Mail", _Class5.Volume3 = "Volume3", _Class5.Volume0 = "Volume0", _Class5.ChromeMinimize = "ChromeMinimize", _Class5);
|
|
50
|
+
const AriaLabels = exports.AriaLabels = (_Class6 = class AriaLabels {}, _Class6.EndCall = "End Call", _Class6.MicMute = "Mute", _Class6.MicUnmute = "Unmute", _Class6.VideoTurnCameraOn = "Turn camera on", _Class6.VideoTurnCameraOff = "Turn camera off", _Class6.IncomingCallArea = "Incoming call area", _Class6.RejectCall = "Reject call", _Class6.AcceptVoiceCall = "Accept voice call", _Class6.AcceptVideoCall = "Accept video Call", _Class6.DeclineCall = "Decline Call", _Class6.AudioCall = "Audio Call", _Class6.VideoCall = "Video Call", _Class6.LetsChatWeAreOnline = "Let's chat we are online", _Class6.UnreadMessageString = "you have new messages", _Class6.Close = "Close", _Class6.ConfirmationPaneConfirm = "Close Chat", _Class6.ConfirmationPaneCancel = "Cancel. Return to Chat", _Class6.DownloadChatTranscript = "Download chat transcript", _Class6.EmailTranscript = "Email Transcript", _Class6.TurnSoundOff = "Turn sound off", _Class6.TurnSoundOn = "Turn sound on", _Class6.Minimize = "Minimize", _Class6.EmailChatTranscriptPane = "Email Chat Transcript Pane", _Class6.InputValidationPaneInput = "Please provide e-mail address to send transcript. The transcript will be sent after the chat ends. Email address text area", _Class6.Save = "Save", _Class6.Cancel = "Cancel", _Class6.ProactiveChatPane = "Proactive Chat Pane", _Class6.ChatNow = "Chat Now", _Class6.ReconnectChatPane = "Reconnect Chat Pane", _Class6.ReconnectChatPaneIcon = "Reconnect Chat Pane Icon", _Class6.ContinueConversation = "Continue conversation", _Class6.StartNewConversation = "Start new conversation", _Class6.InputValidationPaneButtonGroup = "Actions", _Class6.ConfirmationPaneButtonGroup = "Actions", _Class6);
|
|
51
|
+
const EventNames = exports.EventNames = (_Class7 = class EventNames {}, _Class7.OnClick = "OnClick", _Class7.OnEscapeKeyDown = "OnEscapeKeyDown", _Class7.IncomingCallEnded = "IncomingCallEnded", _Class7);
|
|
52
|
+
const Texts = exports.Texts = (_Class8 = class Texts {}, _Class8.IncomingCallTitle = "Incoming Call", _Class8.ChatButtonTitle = "Let's Chat!", _Class8.ChatButtonSubtitle = "We're online.", _Class8.ChatButtonUnreadMessageString = "new messages", _Class8.ChatButtonLargeUnreadMessageString = "99+", _Class8.CloseButtonText = "Close", _Class8.ConfirmationPaneTitle = "Close chat", _Class8.ConfirmationPaneSubtitle = "Do you really want to close this chat?", _Class8.ConfirmButtonText = "Close", _Class8.EmailPlaceHolderText = "johnsmith@outlook.com", _Class8.CancelButtonText = "Cancel", _Class8.DownloadChatTranscriptText = "Download chat transcript", _Class8.EmailTranscriptText = "Email Transcript", _Class8.HeaderIcon = "Chat Icon", _Class8.HeaderTitle = "Let's Chat", _Class8.MinimizeText = "Minimize", _Class8.InputValidationPaneTitleText = "Please provide e-mail address to send transcript.", _Class8.InputValidationPaneSubtitleText = "The transcript will be sent after the chat ends.", _Class8.InvalidInputErrorMessageText = "Enter a valid email address.", _Class8.SendButtonText = "Send", _Class8.SaveButtonText = "Save", _Class8.LoadingPaneTitleText = "Welcome to", _Class8.LoadingPaneSubtitleText = "live chat support ...", _Class8.LoadingPaneSpinnerText = "Loading ...", _Class8.OOOHPaneTitleText = "Thanks for contacting us. You have reached us outside of our operating hours. An agent will respond when we open.", _Class8.PostChatSurveyPaneTitleText = "Post chat survey pane", _Class8.ProactiveChatPaneTitleText = "Welcome to", _Class8.ProactiveChatPaneSubtitleText = "Live chat support!", _Class8.ProactiveChatPaneBodyTitleText = "Hi! Have any questions? I am here to help.", _Class8.ProactiveChatPaneStartButtonText = "Chat Now", _Class8.ReconnectChatPaneTitleText = "Previous session detected", _Class8.ReconnectChatPaneSubtitleText = "We have detected a previous chat session. Would you like to continue with your previous session?", _Class8.ReconnectChatPaneContinueChatButtonText = "Continue conversation", _Class8.ReconnectChatPaneStartNewChatButtonText = "Start new conversation", _Class8);
|
|
@@ -17,6 +17,12 @@ var _reactHooks = require("@fluentui/react-hooks");
|
|
|
17
17
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
18
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
19
19
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
20
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
21
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
22
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
23
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
24
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
25
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
20
26
|
function CurrentCall(props) {
|
|
21
27
|
var _props$controlProps, _defaultCurrentCallPr, _props$controlProps2, _defaultCurrentCallPr2, _props$controlProps3, _defaultCurrentCallPr3, _props$controlProps4, _defaultCurrentCallPr4, _props$controlProps5, _defaultCurrentCallPr5, _props$controlProps6, _defaultCurrentCallPr6, _props$controlProps7, _defaultCurrentCallPr7, _props$controlProps8, _defaultCurrentCallPr8, _props$controlProps9, _props$controlProps0, _defaultCurrentCallPr9, _defaultCurrentCallPr0, _props$styleProps, _props$controlProps1, _defaultCurrentCallPr1, _props$controlProps10, _defaultCurrentCallPr10, _props$controlProps11, _defaultCurrentCallPr11, _props$controlProps12, _props$controlProps13, _defaultCurrentCallPr12, _props$controlProps14, _defaultCurrentCallPr13, _props$controlProps15, _defaultCurrentCallPr14, _props$controlProps16, _defaultCurrentCallPr15, _props$controlProps17, _props$controlProps18, _defaultCurrentCallPr16, _props$controlProps19, _defaultCurrentCallPr17, _props$controlProps20, _defaultCurrentCallPr18, _props$controlProps21, _defaultCurrentCallPr19, _props$controlProps22, _defaultCurrentCallPr20, _props$controlProps23, _defaultCurrentCallPr21, _props$controlProps24, _defaultCurrentCallPr22, _props$controlProps25, _props$controlProps26, _defaultCurrentCallPr23, _props$controlProps27, _defaultCurrentCallPr24, _props$controlProps28, _defaultCurrentCallPr25, _props$controlProps29, _defaultCurrentCallPr26, _props$controlProps30, _props$controlProps31, _defaultCurrentCallPr27, _props$controlProps32, _defaultCurrentCallPr28, _props$controlProps33, _defaultCurrentCallPr29, _props$controlProps34, _defaultCurrentCallPr30, _defaultCurrentCallPr31, _props$controlProps35, _defaultCurrentCallPr32, _props$controlProps36, _defaultCurrentCallPr33, _props$styleProps2, _defaultCurrentCallPr34, _props$styleProps3, _defaultCurrentCallPr35, _props$styleProps4, _defaultCurrentCallPr36, _props$styleProps5, _defaultCurrentCallPr40, _props$styleProps9, _defaultCurrentCallPr41, _props$styleProps0, _defaultCurrentCallPr42, _props$styleProps1, _defaultCurrentCallPr43, _props$styleProps10, _defaultCurrentCallPr44, _props$styleProps11, _props$controlProps43, _defaultCurrentCallPr45, _props$styleProps12, _props$styleProps13, _props$styleProps14, _props$styleProps15, _props$styleProps16, _props$controlProps44, _props$controlProps45, _props$controlProps46, _props$controlProps47, _props$controlProps48, _defaultCurrentCallPr46, _props$controlProps49, _defaultCurrentCallPr47, _props$controlProps50, _props$controlProps51, _defaultCurrentCallPr48, _props$controlProps52, _defaultCurrentCallPr49, _props$controlProps53, _props$controlProps54, _props$controlProps55, _defaultCurrentCallPr50, _props$controlProps56, _defaultCurrentCallPr51, _props$controlProps57, _props$controlProps58, _defaultCurrentCallPr52, _props$controlProps59, _defaultCurrentCallPr53, _props$controlProps60, _props$controlProps61;
|
|
22
28
|
const currentCallId = ((_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.id) ?? ((_defaultCurrentCallPr = _defaultCurrentCallProps.defaultCurrentCallProps.controlProps) === null || _defaultCurrentCallPr === void 0 ? void 0 : _defaultCurrentCallPr.id);
|
|
@@ -103,9 +109,10 @@ function CurrentCall(props) {
|
|
|
103
109
|
}
|
|
104
110
|
}
|
|
105
111
|
};
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
const _useBoolean = (0, _reactHooks.useBoolean)(false),
|
|
113
|
+
_useBoolean2 = _slicedToArray(_useBoolean, 2),
|
|
114
|
+
micState = _useBoolean2[0],
|
|
115
|
+
setMicState = _useBoolean2[1].toggle;
|
|
109
116
|
const endCallButtonProps = Object.assign({}, (_defaultCurrentCallPr31 = _defaultCurrentCallProps.defaultCurrentCallProps.controlProps) === null || _defaultCurrentCallPr31 === void 0 ? void 0 : _defaultCurrentCallPr31.endCallButtonProps, (_props$controlProps35 = props.controlProps) === null || _props$controlProps35 === void 0 ? void 0 : _props$controlProps35.endCallButtonProps);
|
|
110
117
|
const callTimerProps = Object.assign({}, (_defaultCurrentCallPr32 = _defaultCurrentCallProps.defaultCurrentCallProps.controlProps) === null || _defaultCurrentCallPr32 === void 0 ? void 0 : _defaultCurrentCallPr32.callTimerProps, (_props$controlProps36 = props.controlProps) === null || _props$controlProps36 === void 0 ? void 0 : _props$controlProps36.callTimerProps);
|
|
111
118
|
const endCallButtonStyles = Object.assign({}, (_defaultCurrentCallPr33 = _defaultCurrentCallProps.defaultCurrentCallProps.styleProps) === null || _defaultCurrentCallPr33 === void 0 ? void 0 : _defaultCurrentCallPr33.endCallButtonStyleProps, (_props$styleProps2 = props.styleProps) === null || _props$styleProps2 === void 0 ? void 0 : _props$styleProps2.endCallButtonStyleProps);
|
|
@@ -8,8 +8,17 @@ var _react = require("@fluentui/react");
|
|
|
8
8
|
var _react2 = _interopRequireWildcard(require("react"));
|
|
9
9
|
var _utils = require("../../../../common/utils");
|
|
10
10
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
11
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
12
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
13
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
14
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
15
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
16
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
11
17
|
function Timer(props) {
|
|
12
|
-
const
|
|
18
|
+
const _useState = (0, _react2.useState)(0),
|
|
19
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
20
|
+
time = _useState2[0],
|
|
21
|
+
setTime = _useState2[1];
|
|
13
22
|
const running = true;
|
|
14
23
|
const timerStyles = {
|
|
15
24
|
root: props.timerStyles
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("@testing-library/jest-dom/extend-expect");
|
|
4
|
+
var _react = require("@testing-library/react");
|
|
5
|
+
var _BroadcastService = require("../../services/BroadcastService");
|
|
6
|
+
var _ChatButton = _interopRequireDefault(require("./ChatButton"));
|
|
7
|
+
var _LoadingPane = _interopRequireDefault(require("../loadingpane/LoadingPane"));
|
|
8
|
+
var _react2 = _interopRequireDefault(require("react"));
|
|
9
|
+
var _defaultChatButtonProps = require("./common/defaultProps/defaultChatButtonProps");
|
|
10
|
+
var _defaultLoadingPaneProps = require("../loadingpane/common/defaultProps/defaultLoadingPaneProps");
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Repro / catcher for internal tracking — screen reader announces hidden / irrelevant
|
|
16
|
+
* text such as "blank" while navigating the chat surface. NVDA / JAWS announce
|
|
17
|
+
* "blank" when they encounter:
|
|
18
|
+
* - an element with an announceable role (button, link, textbox, listitem,
|
|
19
|
+
* progressbar, etc.) that has an empty accessible name (no aria-label, no
|
|
20
|
+
* aria-labelledby, no associated <label>, and no own text content), OR
|
|
21
|
+
* - a live region (`aria-live="polite"` / `aria-live="assertive"`) that is
|
|
22
|
+
* mounted with empty text content (each tick announces "blank").
|
|
23
|
+
*
|
|
24
|
+
* This catcher walks several rendered LCW surfaces and asserts neither pattern
|
|
25
|
+
* is present. Deterministic DOM contract — no SR needed.
|
|
26
|
+
*
|
|
27
|
+
* Surfaces covered today:
|
|
28
|
+
* - ChatButton (default props) — regression guard; passes today.
|
|
29
|
+
* - ChatButton with notification bubble forced visible at unreadCount=0 —
|
|
30
|
+
* regression guard for the empty-live-region path; passes today.
|
|
31
|
+
* - LoadingPane (default props) — regression guard; passes today.
|
|
32
|
+
*
|
|
33
|
+
* Scope note: the original bug surfaces inside WebChat-rendered chat session
|
|
34
|
+
* content (message bubbles, attachments, agent-supplied HTML), which is not
|
|
35
|
+
* reachable from chat-components unit tests. The Playwright catcher
|
|
36
|
+
* `automation_tests/e2e/areas/accessibility/blankAnnouncements.spec.ts` on
|
|
37
|
+
* `chore/a11y-tooling-foundation` walks the full a11y tree of a built
|
|
38
|
+
* `dist/out.js` and is the right vehicle for enumerating per-offender fixes.
|
|
39
|
+
* Promote additional surfaces here as they are wired into the catcher harness.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
beforeAll(() => {
|
|
43
|
+
(0, _BroadcastService.BroadcastServiceInitialize)("testChannel");
|
|
44
|
+
});
|
|
45
|
+
afterEach(() => {
|
|
46
|
+
(0, _react.cleanup)();
|
|
47
|
+
});
|
|
48
|
+
const ANNOUNCEABLE_ROLES = new Set(["button", "link", "textbox", "combobox", "listbox", "listitem", "menu", "menuitem", "checkbox", "radio", "switch", "tab", "treeitem", "option", "searchbox", "progressbar", "alert", "status"]);
|
|
49
|
+
const ANNOUNCEABLE_TAGS = new Set(["button", "a", "input", "select", "textarea"]);
|
|
50
|
+
const isInsideAriaHidden = el => {
|
|
51
|
+
let cursor = el;
|
|
52
|
+
while (cursor) {
|
|
53
|
+
if (cursor.getAttribute("aria-hidden") === "true") return true;
|
|
54
|
+
cursor = cursor.parentElement;
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
};
|
|
58
|
+
const accessibleNameOf = el => {
|
|
59
|
+
const ariaLabel = (el.getAttribute("aria-label") || "").trim();
|
|
60
|
+
if (ariaLabel) return ariaLabel;
|
|
61
|
+
const labelledBy = (el.getAttribute("aria-labelledby") || "").trim();
|
|
62
|
+
if (labelledBy) {
|
|
63
|
+
const referenced = labelledBy.split(/\s+/).map(id => {
|
|
64
|
+
var _document$getElementB;
|
|
65
|
+
return ((_document$getElementB = document.getElementById(id)) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.textContent) || "";
|
|
66
|
+
}).join(" ").trim();
|
|
67
|
+
if (referenced) return referenced;
|
|
68
|
+
}
|
|
69
|
+
if (el.tagName.toLowerCase() === "input") {
|
|
70
|
+
const id = el.id;
|
|
71
|
+
if (id) {
|
|
72
|
+
var _label$textContent;
|
|
73
|
+
const label = document.querySelector(`label[for="${CSS.escape(id)}"]`);
|
|
74
|
+
const labelText = label === null || label === void 0 || (_label$textContent = label.textContent) === null || _label$textContent === void 0 ? void 0 : _label$textContent.trim();
|
|
75
|
+
if (labelText) return labelText;
|
|
76
|
+
}
|
|
77
|
+
const placeholder = (el.getAttribute("placeholder") || "").trim();
|
|
78
|
+
if (placeholder) return placeholder;
|
|
79
|
+
}
|
|
80
|
+
if (el.tagName.toLowerCase() === "a") {
|
|
81
|
+
const title = (el.getAttribute("title") || "").trim();
|
|
82
|
+
if (title) return title;
|
|
83
|
+
}
|
|
84
|
+
return (el.textContent || "").trim();
|
|
85
|
+
};
|
|
86
|
+
const isAnnounceable = el => {
|
|
87
|
+
if (isInsideAriaHidden(el)) return false;
|
|
88
|
+
const role = (el.getAttribute("role") || "").toLowerCase();
|
|
89
|
+
if (role === "presentation" || role === "none") return false;
|
|
90
|
+
if (role && ANNOUNCEABLE_ROLES.has(role)) return true;
|
|
91
|
+
if (ANNOUNCEABLE_TAGS.has(el.tagName.toLowerCase())) {
|
|
92
|
+
// <input type="hidden"> is not announceable.
|
|
93
|
+
if (el.tagName.toLowerCase() === "input" && (el.getAttribute("type") || "").toLowerCase() === "hidden") {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
};
|
|
100
|
+
const findEmptyAnnounceable = root => {
|
|
101
|
+
return Array.from(root.querySelectorAll("*")).filter(el => isAnnounceable(el) && accessibleNameOf(el) === "");
|
|
102
|
+
};
|
|
103
|
+
const findEmptyLiveRegions = root => {
|
|
104
|
+
return Array.from(root.querySelectorAll("[aria-live]")).filter(el => {
|
|
105
|
+
if (isInsideAriaHidden(el)) return false;
|
|
106
|
+
const live = (el.getAttribute("aria-live") || "").toLowerCase();
|
|
107
|
+
if (live !== "polite" && live !== "assertive") return false;
|
|
108
|
+
return (el.textContent || "").trim() === "";
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
const summarize = offenders => offenders.map(el => ({
|
|
112
|
+
tag: el.tagName.toLowerCase(),
|
|
113
|
+
id: el.id,
|
|
114
|
+
role: el.getAttribute("role"),
|
|
115
|
+
ariaLabel: el.getAttribute("aria-label"),
|
|
116
|
+
ariaLabelledBy: el.getAttribute("aria-labelledby"),
|
|
117
|
+
classes: el.className
|
|
118
|
+
}));
|
|
119
|
+
describe("ChatButton — 'blank' / empty-name announcements (internal tracking regression guard)", () => {
|
|
120
|
+
it("no announceable role/tag in the chat-button subtree may have an empty accessible name", () => {
|
|
121
|
+
const _render = (0, _react.render)(/*#__PURE__*/_react2.default.createElement(_ChatButton.default, _defaultChatButtonProps.defaultChatButtonProps)),
|
|
122
|
+
container = _render.container;
|
|
123
|
+
const button = container.firstElementChild;
|
|
124
|
+
expect(button).not.toBeNull();
|
|
125
|
+
expect(summarize(findEmptyAnnounceable(button))).toEqual([]);
|
|
126
|
+
});
|
|
127
|
+
it("no live region (aria-live=polite/assertive) in the chat-button subtree may be mounted with empty text", () => {
|
|
128
|
+
const props = {
|
|
129
|
+
..._defaultChatButtonProps.defaultChatButtonProps,
|
|
130
|
+
controlProps: {
|
|
131
|
+
..._defaultChatButtonProps.defaultChatButtonProps.controlProps,
|
|
132
|
+
unreadMessageCount: "0",
|
|
133
|
+
hideNotificationBubble: false
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const _render2 = (0, _react.render)(/*#__PURE__*/_react2.default.createElement(_ChatButton.default, props)),
|
|
137
|
+
container = _render2.container;
|
|
138
|
+
const button = container.firstElementChild;
|
|
139
|
+
expect(button).not.toBeNull();
|
|
140
|
+
expect(summarize(findEmptyLiveRegions(button))).toEqual([]);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
describe("LoadingPane — 'blank' / empty-name announcements (internal tracking regression guard)", () => {
|
|
144
|
+
it("no announceable role/tag in the loading-pane subtree may have an empty accessible name", () => {
|
|
145
|
+
const _render3 = (0, _react.render)(/*#__PURE__*/_react2.default.createElement(_LoadingPane.default, _defaultLoadingPaneProps.defaultLoadingPaneProps)),
|
|
146
|
+
container = _render3.container;
|
|
147
|
+
const pane = container.firstElementChild;
|
|
148
|
+
expect(pane).not.toBeNull();
|
|
149
|
+
expect(summarize(findEmptyAnnounceable(pane))).toEqual([]);
|
|
150
|
+
});
|
|
151
|
+
it("no live region (aria-live=polite/assertive) in the loading-pane subtree may be mounted with empty text", () => {
|
|
152
|
+
const _render4 = (0, _react.render)(/*#__PURE__*/_react2.default.createElement(_LoadingPane.default, _defaultLoadingPaneProps.defaultLoadingPaneProps)),
|
|
153
|
+
container = _render4.container;
|
|
154
|
+
const pane = container.firstElementChild;
|
|
155
|
+
expect(pane).not.toBeNull();
|
|
156
|
+
expect(summarize(findEmptyLiveRegions(pane))).toEqual([]);
|
|
157
|
+
});
|
|
158
|
+
});
|