@seamly/web-ui 19.1.2 → 20.0.0-beta.2

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.
Files changed (185) hide show
  1. package/CHANGELOG.md +625 -0
  2. package/build/dist/lib/components.js +2 -1
  3. package/build/dist/lib/components.min.js +1 -1
  4. package/build/dist/lib/index.debug.js +183 -128
  5. package/build/dist/lib/index.debug.min.js +1 -1
  6. package/build/dist/lib/index.debug.min.js.LICENSE.txt +45 -25
  7. package/build/dist/lib/index.js +7292 -7752
  8. package/build/dist/lib/index.min.js +1 -1
  9. package/build/dist/lib/index.min.js.LICENSE.txt +0 -5
  10. package/build/dist/lib/standalone.js +5788 -6255
  11. package/build/dist/lib/standalone.min.js +1 -1
  12. package/build/dist/lib/standalone.min.js.LICENSE.txt +0 -5
  13. package/build/dist/lib/style-guide.js +1935 -1965
  14. package/build/dist/lib/style-guide.min.js +1 -1
  15. package/build/dist/lib/styles.css +1 -1
  16. package/package.json +1 -2
  17. package/src/icons/icon_file-32.svg +1 -1
  18. package/src/javascripts/api/errors/seamly-base-error.js +7 -0
  19. package/src/javascripts/api/index.js +48 -37
  20. package/src/javascripts/api/producer.js +5 -1
  21. package/src/javascripts/config.js +1 -5
  22. package/src/javascripts/domains/app/actions.js +22 -5
  23. package/src/javascripts/domains/config/actions.js +3 -0
  24. package/src/javascripts/domains/config/reducer.js +9 -0
  25. package/src/javascripts/domains/errors/index.js +5 -4
  26. package/src/javascripts/domains/forms/hooks.js +3 -1
  27. package/src/javascripts/domains/forms/provider.js +12 -0
  28. package/src/javascripts/domains/forms/reducer.js +2 -0
  29. package/src/javascripts/domains/i18n/hooks.js +2 -1
  30. package/src/javascripts/domains/i18n/reducer.js +2 -0
  31. package/src/javascripts/domains/interrupt/reducer.js +2 -2
  32. package/src/javascripts/domains/options/middleware.js +15 -31
  33. package/src/javascripts/domains/store/index.js +2 -1
  34. package/src/javascripts/domains/store/state-reducer.js +3 -8
  35. package/src/javascripts/domains/translations/components/options-dialog/form.js +1 -1
  36. package/src/javascripts/domains/translations/components/options-dialog/index.js +15 -1
  37. package/src/javascripts/domains/translations/reducer.js +2 -0
  38. package/src/javascripts/domains/visibility/actions.js +1 -1
  39. package/src/javascripts/domains/visibility/hooks.js +10 -8
  40. package/src/javascripts/domains/visibility/utils.js +1 -2
  41. package/src/javascripts/index.js +7 -2
  42. package/src/javascripts/lib/css.js +7 -1
  43. package/src/javascripts/lib/engine/index.js +4 -3
  44. package/src/javascripts/lib/external-api/index.js +38 -29
  45. package/src/javascripts/package/components.js +2 -1
  46. package/src/javascripts/style-guide/components/app.js +1 -1
  47. package/src/javascripts/style-guide/components/static-core.js +9 -3
  48. package/src/javascripts/style-guide/states.js +203 -298
  49. package/src/javascripts/ui/components/chat-app.js +1 -1
  50. package/src/javascripts/ui/components/conversation/component-filter.js +6 -0
  51. package/src/javascripts/ui/components/conversation/event/carousel-component/index.js +8 -1
  52. package/src/javascripts/ui/components/conversation/event/carousel-message/components/slide.js +2 -3
  53. package/src/javascripts/ui/components/conversation/event/conversation-suggestions.js +70 -0
  54. package/src/javascripts/ui/components/conversation/event/participant.js +2 -5
  55. package/src/javascripts/ui/components/conversation/event/splash.js +26 -0
  56. package/src/javascripts/ui/components/conversation/event/text.js +1 -2
  57. package/src/javascripts/ui/components/core/seamly-core.js +12 -9
  58. package/src/javascripts/ui/components/core/seamly-event-subscriber.js +4 -10
  59. package/src/javascripts/ui/components/core/seamly-instance-functions-loader.js +1 -8
  60. package/src/javascripts/ui/components/entry/entry-container.js +5 -3
  61. package/src/javascripts/ui/components/entry/text-entry/index.js +7 -1
  62. package/src/javascripts/ui/components/entry/text-entry/text-entry-form.js +5 -1
  63. package/src/javascripts/ui/components/entry/toggle-button.js +4 -2
  64. package/src/javascripts/ui/components/entry/upload/file-upload-form.js +1 -1
  65. package/src/javascripts/ui/components/form-controls/error.js +6 -2
  66. package/src/javascripts/ui/components/form-controls/form.js +26 -3
  67. package/src/javascripts/ui/components/layout/app-frame.js +24 -15
  68. package/src/javascripts/ui/components/layout/chat-frame.js +0 -2
  69. package/src/javascripts/ui/components/layout/modal-wrapper.js +0 -80
  70. package/src/javascripts/ui/components/layout/pre-chat-messages.js +45 -0
  71. package/src/javascripts/ui/components/options/options-frame.js +9 -4
  72. package/src/javascripts/ui/components/options/options.js +1 -4
  73. package/src/javascripts/ui/components/options/transcript/index.js +15 -1
  74. package/src/javascripts/ui/components/options/transcript/transcript-form.js +1 -1
  75. package/src/javascripts/ui/components/suggestions/index.js +174 -0
  76. package/src/javascripts/ui/components/suggestions/suggestions-item.js +40 -0
  77. package/src/javascripts/ui/components/suggestions/suggestions-list.js +24 -0
  78. package/src/javascripts/ui/components/view/app-view.js +21 -0
  79. package/src/javascripts/ui/components/view/deprecated-view.js +30 -0
  80. package/src/javascripts/ui/components/view/index.js +27 -0
  81. package/src/javascripts/ui/components/view/inline-view.js +45 -0
  82. package/src/javascripts/ui/components/view/window-view/collapse-button.js +20 -0
  83. package/src/javascripts/ui/components/view/window-view/index.js +82 -0
  84. package/src/javascripts/ui/components/view/window-view/window-open-button.js +68 -0
  85. package/src/javascripts/ui/components/widgets/lightbox.js +7 -2
  86. package/src/javascripts/ui/hooks/component-helper-hooks.js +0 -9
  87. package/src/javascripts/ui/hooks/seamly-hooks.js +0 -1
  88. package/src/javascripts/ui/hooks/seamly-state-hooks.js +28 -4
  89. package/src/javascripts/ui/hooks/use-seamly-chat.js +12 -3
  90. package/src/javascripts/ui/hooks/use-seamly-commands.js +4 -31
  91. package/src/javascripts/ui/utils/seamly-utils.js +2 -14
  92. package/src/stylesheets/1-settings/_animations.scss +0 -6
  93. package/src/stylesheets/1-settings/_config.scss +34 -35
  94. package/src/stylesheets/2-tools/_functions.scss +0 -5
  95. package/src/stylesheets/2-tools/_mixins.scss +4 -16
  96. package/src/stylesheets/3-app/_app.scss +78 -135
  97. package/src/stylesheets/4-base/_a11y.scss +0 -3
  98. package/src/stylesheets/4-base/_elements.scss +0 -11
  99. package/src/stylesheets/4-base/_formelements.scss +4 -14
  100. package/src/stylesheets/5-components/_avatar.scss +2 -44
  101. package/src/stylesheets/5-components/_buttons.scss +6 -45
  102. package/src/stylesheets/5-components/_chat-status.scss +14 -38
  103. package/src/stylesheets/5-components/_choice-prompt.scss +33 -2
  104. package/src/stylesheets/5-components/_collapse-button.scss +16 -0
  105. package/src/stylesheets/5-components/_conversation.scss +26 -2
  106. package/src/stylesheets/5-components/_disclaimer.scss +10 -12
  107. package/src/stylesheets/5-components/_divider.scss +7 -4
  108. package/src/stylesheets/5-components/_error.scss +1 -1
  109. package/src/stylesheets/5-components/_form.scss +9 -0
  110. package/src/stylesheets/5-components/_icon.scss +10 -1
  111. package/src/stylesheets/5-components/_idle.scss +0 -8
  112. package/src/stylesheets/5-components/_input.scss +14 -20
  113. package/src/stylesheets/5-components/_interrupt.scss +0 -2
  114. package/src/stylesheets/5-components/_loader.scss +0 -32
  115. package/src/stylesheets/5-components/_message-author.scss +40 -0
  116. package/src/stylesheets/5-components/_message-body.scss +194 -0
  117. package/src/stylesheets/5-components/_message-card.scss +55 -0
  118. package/src/stylesheets/5-components/_message-carousel.scss +143 -0
  119. package/src/stylesheets/5-components/_message-count.scss +11 -28
  120. package/src/stylesheets/5-components/_message-cta.scss +23 -0
  121. package/src/stylesheets/5-components/_message-info.scss +11 -0
  122. package/src/stylesheets/5-components/_message-translation-info.scss +17 -0
  123. package/src/stylesheets/5-components/_message.scss +13 -364
  124. package/src/stylesheets/5-components/_modal.scss +28 -58
  125. package/src/stylesheets/5-components/_notification.scss +0 -5
  126. package/src/stylesheets/5-components/_options.scss +27 -42
  127. package/src/stylesheets/5-components/_pre-chat-messages.scss +30 -0
  128. package/src/stylesheets/5-components/_prompt.scss +0 -8
  129. package/src/stylesheets/5-components/_skip-link.scss +3 -3
  130. package/src/stylesheets/5-components/_suggestions.scss +96 -0
  131. package/src/stylesheets/5-components/_unstarted.scss +50 -0
  132. package/src/stylesheets/5-components/_upload.scss +26 -28
  133. package/src/stylesheets/5-components/_window-open-button.scss +39 -0
  134. package/src/stylesheets/6-webui-only/_hover.scss +151 -0
  135. package/src/stylesheets/6-webui-only/_scrollbar.scss +31 -0
  136. package/src/stylesheets/7-deprecated/1-settings/_animations.scss +43 -0
  137. package/src/stylesheets/7-deprecated/1-settings/_config.scss +105 -0
  138. package/src/stylesheets/7-deprecated/2-tools/_functions.scss +22 -0
  139. package/src/stylesheets/7-deprecated/2-tools/_mixins.scss +77 -0
  140. package/src/stylesheets/7-deprecated/3-app/_app.scss +214 -0
  141. package/src/stylesheets/7-deprecated/4-base/_a11y.scss +14 -0
  142. package/src/stylesheets/7-deprecated/4-base/_elements.scss +21 -0
  143. package/src/stylesheets/7-deprecated/4-base/_formelements.scss +57 -0
  144. package/src/stylesheets/{5-components → 7-deprecated/5-components}/_agent-info.scss +0 -0
  145. package/src/stylesheets/7-deprecated/5-components/_avatar.scss +64 -0
  146. package/src/stylesheets/7-deprecated/5-components/_buttons.scss +94 -0
  147. package/src/stylesheets/{5-components → 7-deprecated/5-components}/_card.scss +0 -0
  148. package/src/stylesheets/{5-components → 7-deprecated/5-components}/_carousel.scss +0 -0
  149. package/src/stylesheets/7-deprecated/5-components/_character-limit.scss +36 -0
  150. package/src/stylesheets/{5-components/_cobrowsing.scss → 7-deprecated/5-components/_chat-status.scss} +18 -16
  151. package/src/stylesheets/7-deprecated/5-components/_choice-prompt.scss +27 -0
  152. package/src/stylesheets/7-deprecated/5-components/_collapse-button.scss +17 -0
  153. package/src/stylesheets/7-deprecated/5-components/_conversation.scss +44 -0
  154. package/src/stylesheets/7-deprecated/5-components/_disclaimer.scss +36 -0
  155. package/src/stylesheets/7-deprecated/5-components/_divider.scss +91 -0
  156. package/src/stylesheets/7-deprecated/5-components/_error.scss +24 -0
  157. package/src/stylesheets/{5-components → 7-deprecated/5-components}/_faq.scss +8 -3
  158. package/src/stylesheets/{5-components → 7-deprecated/5-components}/_header-controls.scss +0 -0
  159. package/src/stylesheets/7-deprecated/5-components/_icon.scss +4 -0
  160. package/src/stylesheets/7-deprecated/5-components/_idle.scss +61 -0
  161. package/src/stylesheets/7-deprecated/5-components/_input.scss +78 -0
  162. package/src/stylesheets/7-deprecated/5-components/_interrupt.scss +35 -0
  163. package/src/stylesheets/7-deprecated/5-components/_loader.scss +78 -0
  164. package/src/stylesheets/7-deprecated/5-components/_message-count.scss +41 -0
  165. package/src/stylesheets/7-deprecated/5-components/_message.scss +385 -0
  166. package/src/stylesheets/7-deprecated/5-components/_modal.scss +138 -0
  167. package/src/stylesheets/7-deprecated/5-components/_notification.scss +20 -0
  168. package/src/stylesheets/7-deprecated/5-components/_options.scss +286 -0
  169. package/src/stylesheets/7-deprecated/5-components/_prompt.scss +44 -0
  170. package/src/stylesheets/7-deprecated/5-components/_skip-link.scss +21 -0
  171. package/src/stylesheets/{5-components → 7-deprecated/5-components}/_svg-graphic.scss +0 -0
  172. package/src/stylesheets/7-deprecated/5-components/_upload.scss +213 -0
  173. package/src/stylesheets/deprecated-view.scss +64 -0
  174. package/src/stylesheets/styles-webui-only.scss +3 -0
  175. package/src/stylesheets/styles.scss +15 -25
  176. package/webpack/config.site.js +4 -0
  177. package/webpack/defaults.js +5 -0
  178. package/src/.DS_Store +0 -0
  179. package/src/javascripts/ui/components/conversation/event/hooks/use-text-rendering.js +0 -35
  180. package/src/javascripts/ui/components/faq/faq.js +0 -162
  181. package/src/javascripts/ui/components/layout/view.js +0 -36
  182. package/src/javascripts/ui/components/options/cobrowsing.js +0 -110
  183. package/src/javascripts/ui/components/warnings/cobrowsing-active-frame.js +0 -29
  184. package/src/javascripts/ui/components/warnings/cobrowsing-active.js +0 -33
  185. package/src/stylesheets/5-components/_modal_mode.scss +0 -108
@@ -0,0 +1,64 @@
1
+ // ##### STYLES #####
2
+ // ==================
3
+ // LIBRARIES
4
+ // ---------
5
+ @import 'include-media/dist/include-media';
6
+
7
+ // SETTINGS
8
+ // --------
9
+ @import '7-deprecated/1-settings/config';
10
+ @import '7-deprecated/1-settings/animations';
11
+
12
+ // TOOLS
13
+ // -----
14
+ @import '7-deprecated/2-tools/functions';
15
+ @import '7-deprecated/2-tools/mixins';
16
+
17
+ // APP
18
+ // ---
19
+ @import '7-deprecated/3-app/app';
20
+
21
+ // SCOPED WITHIN APP
22
+ // -----------------
23
+ .#{$n}-app--deprecated {
24
+ // BASE
25
+ @import '7-deprecated/4-base/elements';
26
+ @import '7-deprecated/4-base/formelements';
27
+
28
+ // COMPONENTS
29
+ @import '7-deprecated/5-components/header-controls';
30
+ @import '7-deprecated/5-components/agent-info';
31
+ @import '7-deprecated/5-components/avatar';
32
+ @import '7-deprecated/5-components/buttons';
33
+ @import '7-deprecated/5-components/choice-prompt';
34
+ @import '7-deprecated/5-components/conversation';
35
+ @import '7-deprecated/5-components/divider';
36
+ @import '7-deprecated/5-components/loader';
37
+ @import '7-deprecated/5-components/message';
38
+ @import '7-deprecated/5-components/message-count';
39
+ @import '7-deprecated/5-components/icon';
40
+ @import '7-deprecated/5-components/input';
41
+ @import '7-deprecated/5-components/faq';
42
+ @import '7-deprecated/5-components/interrupt';
43
+ @import '7-deprecated/5-components/skip-link';
44
+ @import '7-deprecated/5-components/svg-graphic';
45
+ @import '7-deprecated/5-components/disclaimer';
46
+ @import '7-deprecated/5-components/idle';
47
+ @import '7-deprecated/5-components/prompt';
48
+ @import '7-deprecated/5-components/options';
49
+ @import '7-deprecated/5-components/chat-status';
50
+ @import '7-deprecated/5-components/upload';
51
+ @import '7-deprecated/5-components/error';
52
+ @import '7-deprecated/5-components/notification';
53
+ @import '7-deprecated/5-components/character-limit';
54
+ @import '7-deprecated/5-components/card';
55
+ @import '7-deprecated/5-components/carousel';
56
+ @import '7-deprecated/5-components/collapse-button';
57
+ }
58
+
59
+ .#{$n}-app--deprecated,
60
+ .#{$n}-app__live-container {
61
+ @import '7-deprecated/4-base/a11y';
62
+ }
63
+
64
+ @import '7-deprecated/5-components/modal';
@@ -0,0 +1,3 @@
1
+ @import '1-settings/config';
2
+ @import '6-webui-only/hover';
3
+ @import '6-webui-only/scrollbar';
@@ -1,59 +1,44 @@
1
- // ##### STYLES #####
2
- // ==================
3
- // LIBRARIES
4
- // ---------
5
1
  @import 'include-media/dist/include-media';
6
2
 
7
- // SETTINGS
8
- // --------
9
3
  @import '1-settings/config';
10
4
  @import '1-settings/animations';
11
5
 
12
- // TOOLS
13
- // -----
14
6
  @import '2-tools/functions';
15
7
  @import '2-tools/mixins';
16
8
 
17
- // APP
18
- // ---
19
9
  @import '3-app/app';
10
+ @import '5-components/buttons';
20
11
 
21
- // SCOPED WITHIN APP
22
- // -----------------
23
12
  .#{$n}-app {
24
- // BASE
25
13
  @import '4-base/elements';
26
14
  @import '4-base/formelements';
27
-
28
- // COMPONENTS
29
- @import '5-components/agent-info';
30
15
  @import '5-components/avatar';
31
- @import '5-components/buttons';
32
16
  @import '5-components/choice-prompt';
33
17
  @import '5-components/conversation';
34
18
  @import '5-components/divider';
35
- @import '5-components/header-controls';
36
19
  @import '5-components/loader';
37
20
  @import '5-components/message';
38
- @import '5-components/message-count';
21
+ @import '5-components/message-author';
22
+ @import '5-components/message-info';
23
+ @import '5-components/message-translation-info';
24
+ @import '5-components/message-card';
25
+ @import '5-components/message-carousel';
26
+ @import '5-components/message-cta';
39
27
  @import '5-components/icon';
28
+ @import '5-components/form';
40
29
  @import '5-components/input';
41
- @import '5-components/faq';
42
30
  @import '5-components/interrupt';
43
31
  @import '5-components/skip-link';
44
- @import '5-components/svg-graphic';
45
32
  @import '5-components/disclaimer';
46
33
  @import '5-components/idle';
47
34
  @import '5-components/prompt';
48
35
  @import '5-components/options';
49
- @import '5-components/cobrowsing'; // @todo: deprecate
50
36
  @import '5-components/chat-status';
51
37
  @import '5-components/upload';
52
38
  @import '5-components/error';
53
39
  @import '5-components/notification';
54
40
  @import '5-components/character-limit';
55
- @import '5-components/card';
56
- @import '5-components/carousel';
41
+ @import '5-components/collapse-button';
57
42
  }
58
43
 
59
44
  .#{$n}-app,
@@ -61,5 +46,10 @@
61
46
  @import '4-base/a11y';
62
47
  }
63
48
 
49
+ @import '5-components/message-body';
50
+ @import '5-components/message-count';
51
+ @import '5-components/suggestions';
64
52
  @import '5-components/modal';
65
- @import '5-components/modal_mode';
53
+ @import '5-components/window-open-button';
54
+ @import '5-components/pre-chat-messages';
55
+ @import '5-components/unstarted';
@@ -40,6 +40,10 @@ module.exports = (env = {}, argv = {}, configOverrides = {}, options = {}) => {
40
40
  'demos/window/index': path.join(PUBLIC_ROOT, '/demos/window/index.js'),
41
41
  'demos/app/index': path.join(PUBLIC_ROOT, '/demos/app/index.js'),
42
42
  'style-guide/index': path.join(PUBLIC_ROOT, '/style-guide/index.js'),
43
+ 'style-guide/deprecated-view': path.join(
44
+ PUBLIC_ROOT,
45
+ '/style-guide/deprecated-view.js',
46
+ ),
43
47
  },
44
48
  module: {
45
49
  rules: [
@@ -47,6 +47,11 @@ const ALIASSES = {
47
47
  'stylesheets',
48
48
  'styles.scss',
49
49
  ),
50
+ '@seamly/web-ui/src/stylesheets/styles-webui-only.scss': path.resolve(
51
+ SRC_ROOT,
52
+ 'stylesheets',
53
+ 'styles-webui-only.scss',
54
+ ),
50
55
  '@seamly/web-ui/src/stylesheets/style-guide.scss': path.resolve(
51
56
  SRC_ROOT,
52
57
  'stylesheets',
package/src/.DS_Store DELETED
Binary file
@@ -1,35 +0,0 @@
1
- import Mustache from 'mustache'
2
-
3
- Mustache.escape = function (escapeText) {
4
- return escapeText
5
- }
6
-
7
- const parseLinkVariable = (variable) => {
8
- return `<a href='${variable.url}' data-link-id='${variable.id}' ${
9
- variable.newTab ? 'target="_blank"' : ''
10
- }>${variable.name}</a>`
11
- }
12
-
13
- export function parseRichText(text, variables = {}) {
14
- const view = {}
15
- Object.entries(variables).forEach(([key, variable]) => {
16
- switch (variable.type) {
17
- case 'link':
18
- view[key] = parseLinkVariable(variable)
19
- break
20
- case 'text':
21
- view[key] = variable.value
22
- break
23
- }
24
- }, {})
25
-
26
- // Disable escaping as we'll be generating HTML
27
- const oldEscape = Mustache.escape
28
- Mustache.escape = function (escapeText) {
29
- return escapeText
30
- }
31
- const output = Mustache.render(text, view)
32
- Mustache.escape = oldEscape
33
-
34
- return output
35
- }
@@ -1,162 +0,0 @@
1
- import { useEffect, useRef, useMemo } from 'preact/hooks'
2
- import { className } from '../../../lib/css'
3
- import Icon from '../layout/icon'
4
- import { actionTypes } from '../../utils/seamly-utils'
5
- import { runIfElementContainsOrHasFocus } from '../../utils/general-utils'
6
- import useSeamlyCommands from '../../hooks/use-seamly-commands'
7
- import {
8
- useSeamlyServiceData,
9
- useSeamlyLayoutMode,
10
- } from '../../hooks/seamly-state-hooks'
11
- import { useGeneratedId } from '../../hooks/utility-hooks'
12
- import { useSkiplinkTargetFocusing } from '../../hooks/focus-helper-hooks'
13
- import { useLiveRegion } from '../../hooks/live-region-hooks'
14
- import useSeamlyIdleDetachCountdown from '../../hooks/use-seamly-idle-detach-countdown'
15
- import useSeamlyResumeConversationPrompt from '../../hooks/use-seamly-resume-conversation-prompt'
16
- import { useI18n } from '../../../domains/i18n'
17
- import InOutTransition, {
18
- transitionStartStates,
19
- } from '../widgets/in-out-transition'
20
- import { useTranslatedEventData } from '../../../domains/translations'
21
- import { useInterrupt } from '../../../domains/interrupt'
22
- import { useUserHasResponded } from '../../../domains/app'
23
-
24
- const Faq = () => {
25
- const { t } = useI18n()
26
- const { sendAction, addMessageBubble } = useSeamlyCommands()
27
- const sectionId = useGeneratedId()
28
- const focusSkiplinkTarget = useSkiplinkTargetFocusing()
29
- const { sendPolite } = useLiveRegion()
30
- const { hasInterrupt } = useInterrupt()
31
- const { hasCountdown, endCountdown } = useSeamlyIdleDetachCountdown()
32
- const { hasPrompt, continueChat } = useSeamlyResumeConversationPrompt()
33
-
34
- const lastFaqEventPayload = useSeamlyServiceData('suggestion')
35
- const [eventBody] = useTranslatedEventData({ payload: lastFaqEventPayload })
36
- const faqs = useMemo(() => {
37
- const newFaqs = lastFaqEventPayload && !hasInterrupt ? eventBody : []
38
- const itemBaseClass = `faqs__item`
39
- return newFaqs.map(({ categories = [], ...faqRest }) => ({
40
- ...faqRest,
41
- categories,
42
- classNames: [
43
- itemBaseClass,
44
- ...categories.map(
45
- (cat) =>
46
- `faqs__item--${String(cat)
47
- .toLowerCase()
48
- .replace(/[^a-z0-9_\\-]/, '')}`,
49
- ),
50
- ],
51
- }))
52
- }, [lastFaqEventPayload, hasInterrupt, eventBody])
53
-
54
- const prevFaqs = useRef(null)
55
- const prevHasFaqs = useRef(false)
56
-
57
- const { isInline } = useSeamlyLayoutMode()
58
- const hasResponded = useUserHasResponded()
59
- const hideForWindow = !isInline && hasResponded
60
- const prevHideForWindow = useRef(hideForWindow)
61
-
62
- const hasFaqs = !!faqs.length
63
- const showFaqContainer = hasFaqs && !hideForWindow
64
- const previousRenderedFaqList = useRef([])
65
- const renderedFaqList = hasFaqs ? faqs : previousRenderedFaqList.current
66
- previousRenderedFaqList.current = renderedFaqList
67
-
68
- const containerRef = useRef(null)
69
-
70
- useEffect(() => {
71
- if (prevFaqs.current !== faqs && !hideForWindow) {
72
- if (hasFaqs) {
73
- const politeText = prevHasFaqs.current
74
- ? t('faq.srUpdatedText')
75
- : t('faq.srAvailableText')
76
- setTimeout(() => {
77
- sendPolite(politeText)
78
- }, 30)
79
- } else if (prevHasFaqs.current) {
80
- sendPolite(t('faq.srUnavailableText'))
81
- }
82
- prevFaqs.current = faqs
83
- }
84
-
85
- if (!prevHideForWindow.current && hideForWindow) {
86
- runIfElementContainsOrHasFocus(containerRef.current, focusSkiplinkTarget)
87
- sendPolite(t('faq.srUnavailableText'))
88
- } else if (!hasFaqs && prevHasFaqs.current) {
89
- runIfElementContainsOrHasFocus(containerRef.current, focusSkiplinkTarget)
90
- }
91
-
92
- prevHasFaqs.current = hasFaqs
93
- prevHideForWindow.current = hideForWindow
94
- }, [hasFaqs, faqs, hideForWindow, focusSkiplinkTarget, sendPolite, t])
95
-
96
- const onFaqClickHandler = ({ id, question }) => {
97
- if (hasCountdown) {
98
- endCountdown(true)
99
- }
100
-
101
- if (hasPrompt) {
102
- continueChat()
103
- }
104
-
105
- sendAction({
106
- type: actionTypes.custom,
107
- originMessage: lastFaqEventPayload.id,
108
- body: {
109
- type: 'faqclick',
110
- body: {
111
- faqId: id,
112
- faqQuestion: question,
113
- },
114
- },
115
- })
116
-
117
- addMessageBubble(question)
118
- focusSkiplinkTarget()
119
- }
120
-
121
- const headingText = t('faq.headingText')
122
- const ContainerElement = headingText ? 'section' : 'div'
123
-
124
- return (
125
- <InOutTransition
126
- isActive={showFaqContainer}
127
- transitionStartState={transitionStartStates.notRendered}
128
- >
129
- <ContainerElement
130
- className={className('faqs')}
131
- aria-labelledby={headingText ? sectionId : null}
132
- ref={containerRef}
133
- >
134
- {headingText && (
135
- <h2 id={sectionId} className={className('faqs__heading')}>
136
- {headingText}
137
- </h2>
138
- )}
139
- {!!renderedFaqList.length && (
140
- <ul className={className('faqs__list')}>
141
- {renderedFaqList.map((faq) => (
142
- <li key={faq.id.toString()} className={className(faq.classNames)}>
143
- <button
144
- type="button"
145
- onClick={() => {
146
- onFaqClickHandler(faq)
147
- }}
148
- className={className('button', 'button--secondary')}
149
- >
150
- <Icon name="chevronRight" size="8" />
151
- {faq.question}
152
- </button>
153
- </li>
154
- ))}
155
- </ul>
156
- )}
157
- </ContainerElement>
158
- </InOutTransition>
159
- )
160
- }
161
-
162
- export default Faq
@@ -1,36 +0,0 @@
1
- import ModalWrapper from './modal-wrapper'
2
- import AppFrame from './app-frame'
3
- import ChatFrame from './chat-frame'
4
- import ToggleButton from '../entry/toggle-button'
5
- import AgentInfo from './agent-info'
6
- import Header from './header'
7
- import Conversation from '../conversation/conversation'
8
- import EntryContainer from '../entry/entry-container'
9
- import Interrupt from './interrupt'
10
- import { useSeamlyChat, useSeamlyLayoutMode } from '../../hooks/seamly-hooks'
11
- import { useVisibility } from '../../../domains/visibility'
12
-
13
- const View = () => {
14
- const { isVisible } = useVisibility()
15
- const { openChat, closeChat } = useSeamlyChat()
16
- const { isModal } = useSeamlyLayoutMode()
17
-
18
- return (
19
- isVisible && (
20
- <ModalWrapper>
21
- <AppFrame>
22
- {!isModal && <ToggleButton onOpenChat={openChat} />}
23
- <Header onCloseChat={closeChat}>
24
- <AgentInfo />
25
- </Header>
26
- <ChatFrame interruptComponent={Interrupt}>
27
- <Conversation />
28
- <EntryContainer />
29
- </ChatFrame>
30
- </AppFrame>
31
- </ModalWrapper>
32
- )
33
- )
34
- }
35
-
36
- export default View
@@ -1,110 +0,0 @@
1
- import { useRef, useEffect, useState } from 'preact/hooks'
2
- import OptionsFrame from './options-frame'
3
- import {
4
- useSeamlyOptions,
5
- useOptionButton,
6
- useCobrowsingContainer,
7
- useGeneratedId,
8
- useLiveRegion,
9
- } from '../../hooks/seamly-hooks'
10
- import { useI18n } from '../../../domains/i18n'
11
- import { className } from '../../../lib/css'
12
- import { featureKeys } from '../../utils/seamly-utils'
13
- import {
14
- focusElement,
15
- runIfElementContainsOrHasFocus,
16
- } from '../../utils/general-utils'
17
-
18
- const Cobrowsing = () => {
19
- const { t } = useI18n()
20
- const cobrowsingDescriptionId = useGeneratedId()
21
- const { userSelectedOptions, features, setUserSelectedOption, hideOption } =
22
- useSeamlyOptions()
23
- const { enabled: canActivateCobrowsing } = features.cobrowsing || {}
24
- const prevCanActivateCobrowsing = useRef(null)
25
- const [cobrowsingToggleActive, setCobrowsingToggleActive] = useState(
26
- canActivateCobrowsing,
27
- )
28
- const { focusButton } = useOptionButton()
29
- const { focusContainer } = useCobrowsingContainer()
30
- const { sendAssertive } = useLiveRegion()
31
- const cancelButton = useRef(null)
32
- const toggleButton = useRef(null)
33
-
34
- useEffect(() => {
35
- const focusFn = () => {
36
- focusElement(cancelButton.current)
37
- }
38
-
39
- if (!canActivateCobrowsing && prevCanActivateCobrowsing.current === true) {
40
- sendAssertive(t('options.cobrowsing.cobrowsingUnavailable'))
41
- setUserSelectedOption(featureKeys.cobrowsing, false)
42
- runIfElementContainsOrHasFocus(toggleButton.current, focusFn)
43
- }
44
-
45
- if (canActivateCobrowsing && prevCanActivateCobrowsing.current === false) {
46
- sendAssertive(t('options.cobrowsing.srCobrowsingAvailable'))
47
- }
48
- setCobrowsingToggleActive(canActivateCobrowsing)
49
- prevCanActivateCobrowsing.current = canActivateCobrowsing
50
- }, [canActivateCobrowsing, setUserSelectedOption, sendAssertive, t])
51
-
52
- const toggleAndFocus = (isCancel) => {
53
- if (!isCancel && !userSelectedOptions.cobrowsing) {
54
- focusContainer()
55
- } else {
56
- focusButton()
57
- }
58
- }
59
-
60
- const onToggleClickHandler = () => {
61
- hideOption()
62
- toggleAndFocus()
63
- setUserSelectedOption(
64
- featureKeys.cobrowsing,
65
- !userSelectedOptions.cobrowsing,
66
- )
67
- sendAssertive(t('options.cobrowsing.srStartedCobrowsingText'))
68
- }
69
-
70
- const onCancelClickHandler = () => {
71
- toggleAndFocus(true)
72
- }
73
-
74
- return (
75
- <OptionsFrame
76
- headingText={t('options.cobrowsing.title')}
77
- cancelButtonText={t('options.cancelButtonText')}
78
- onCancel={onCancelClickHandler}
79
- disableButtonFocusing={true}
80
- cancelButtonRef={cancelButton}
81
- >
82
- <p
83
- className={className('options__description')}
84
- id={cobrowsingDescriptionId}
85
- >
86
- {t('options.cobrowsing.description')}
87
- </p>
88
- {!cobrowsingToggleActive && (
89
- <p className={className('notification')}>
90
- {t('options.cobrowsing.cobrowsingUnavailable')}
91
- </p>
92
- )}
93
- {cobrowsingToggleActive && (
94
- <button
95
- type="button"
96
- className={className(['button', 'button--primary'])}
97
- onClick={onToggleClickHandler}
98
- aria-describedby={cobrowsingDescriptionId}
99
- ref={toggleButton}
100
- >
101
- {userSelectedOptions.cobrowsing
102
- ? t('options.cobrowsing.labelTurnOff')
103
- : t('options.cobrowsing.labelTurnOn')}
104
- </button>
105
- )}
106
- </OptionsFrame>
107
- )
108
- }
109
-
110
- export default Cobrowsing
@@ -1,29 +0,0 @@
1
- import { useEffect, useRef } from 'preact/hooks'
2
- import CobrowsingActive from './cobrowsing-active'
3
- import { useLiveRegion, useSeamlyOptions } from '../../hooks/seamly-hooks'
4
- import { useI18n } from '../../../domains/i18n'
5
- import { useInterrupt } from '../../../domains/interrupt'
6
-
7
- const CobrowsingActiveFrame = () => {
8
- const { t } = useI18n()
9
- const { userSelectedOptions } = useSeamlyOptions()
10
- const { hasInterrupt } = useInterrupt()
11
- const { cobrowsing } = userSelectedOptions
12
- const prevCobrowsing = useRef(cobrowsing)
13
- const { sendPolite } = useLiveRegion()
14
-
15
- useEffect(() => {
16
- if (!cobrowsing && prevCobrowsing.current) {
17
- // This timeout is required as the live announce may be swallowed due to other
18
- // announcements around cobrowsing.
19
- setTimeout(() => {
20
- sendPolite(t('options.cobrowsing.srStoppedCobrowsingText'))
21
- }, 300)
22
- }
23
- prevCobrowsing.current = cobrowsing
24
- }, [cobrowsing, t, sendPolite])
25
-
26
- return cobrowsing && !hasInterrupt && <CobrowsingActive />
27
- }
28
-
29
- export default CobrowsingActiveFrame
@@ -1,33 +0,0 @@
1
- import {
2
- useSeamlyOptions,
3
- useSkiplinkTargetFocusing,
4
- useCobrowsingContainer,
5
- } from '../../hooks/seamly-hooks'
6
- import { useI18n } from '../../../domains/i18n'
7
- import { featureKeys } from '../../utils/seamly-utils'
8
- import ChatStatus from '../chat-status'
9
-
10
- const CobrowsingActive = () => {
11
- const { t } = useI18n()
12
- const { setUserSelectedOption } = useSeamlyOptions()
13
- const focusSkiplinkTarget = useSkiplinkTargetFocusing()
14
- const { id } = useCobrowsingContainer()
15
-
16
- const onClickHandler = () => {
17
- setUserSelectedOption(featureKeys.cobrowsing, false)
18
- focusSkiplinkTarget()
19
- }
20
-
21
- return (
22
- <ChatStatus
23
- type="cobrowsing"
24
- id={id}
25
- label={t('options.cobrowsing.cobrowsingActiveText')}
26
- onButtonClick={onClickHandler}
27
- buttonText={t('options.cobrowsing.stopCobrowsingText')}
28
- srButtonText={t('options.cobrowsing.srStopCobrowsingText')}
29
- />
30
- )
31
- }
32
-
33
- export default CobrowsingActive