@azure/communication-react 1.18.0-alpha-202407110015 → 1.18.0-alpha-202407130015

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 (77) hide show
  1. package/dist/communication-react.d.ts +91 -14
  2. package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-BHcuHeib.js → ChatMessageComponentAsRichTextEditBox-p1814UvI.js} +10 -9
  3. package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-BHcuHeib.js.map → ChatMessageComponentAsRichTextEditBox-p1814UvI.js.map} +1 -1
  4. package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-7S-tHnhY.js → RichTextSendBoxWrapper-C2KzFhtR.js} +9 -8
  5. package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-7S-tHnhY.js.map → RichTextSendBoxWrapper-C2KzFhtR.js.map} +1 -1
  6. package/dist/dist-cjs/communication-react/{index-B2uDEMiK.js → index-DwCOuhpb.js} +25801 -25660
  7. package/dist/dist-cjs/communication-react/index-DwCOuhpb.js.map +1 -0
  8. package/dist/dist-cjs/communication-react/index.js +10 -7
  9. package/dist/dist-cjs/communication-react/index.js.map +1 -1
  10. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  11. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
  12. package/dist/dist-esm/acs-ui-javascript-loaders/src/callCompositeLoader.d.ts +19 -0
  13. package/dist/dist-esm/acs-ui-javascript-loaders/src/callCompositeLoader.js +51 -0
  14. package/dist/dist-esm/acs-ui-javascript-loaders/src/callCompositeLoader.js.map +1 -0
  15. package/dist/dist-esm/acs-ui-javascript-loaders/src/index.d.ts +5 -0
  16. package/dist/dist-esm/acs-ui-javascript-loaders/src/index.js +5 -0
  17. package/dist/dist-esm/acs-ui-javascript-loaders/src/index.js.map +1 -0
  18. package/dist/dist-esm/acs-ui-javascript-loaders/src/outboundCallCompositeLoader.d.ts +19 -0
  19. package/dist/dist-esm/acs-ui-javascript-loaders/src/outboundCallCompositeLoader.js +57 -0
  20. package/dist/dist-esm/acs-ui-javascript-loaders/src/outboundCallCompositeLoader.js.map +1 -0
  21. package/dist/dist-esm/calling-component-bindings/src/hooks/usePropsFor.js +1 -1
  22. package/dist/dist-esm/calling-component-bindings/src/hooks/usePropsFor.js.map +1 -1
  23. package/dist/dist-esm/calling-component-bindings/src/notificationStackSelector.d.ts +2 -2
  24. package/dist/dist-esm/calling-component-bindings/src/notificationStackSelector.js +2 -4
  25. package/dist/dist-esm/calling-component-bindings/src/notificationStackSelector.js.map +1 -1
  26. package/dist/dist-esm/communication-react/src/index.d.ts +3 -1
  27. package/dist/dist-esm/communication-react/src/index.js +2 -0
  28. package/dist/dist-esm/communication-react/src/index.js.map +1 -1
  29. package/dist/dist-esm/react-components/src/components/ChatMessage/MessageComponents/ChatMessageComponentAsMessageBubble.js +1 -1
  30. package/dist/dist-esm/react-components/src/components/ChatMessage/MessageComponents/ChatMessageComponentAsMessageBubble.js.map +1 -1
  31. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsEditBox.js +1 -1
  32. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsEditBox.js.map +1 -1
  33. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.js +1 -1
  34. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMessageComponentAsRichTextEditBox.js.map +1 -1
  35. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponentAsMessageBubble.js +6 -2
  36. package/dist/dist-esm/react-components/src/components/ChatMessage/MyMessageComponents/ChatMyMessageComponentAsMessageBubble.js.map +1 -1
  37. package/dist/dist-esm/react-components/src/components/IncomingCallNotification.d.ts +43 -5
  38. package/dist/dist-esm/react-components/src/components/IncomingCallNotification.js +9 -7
  39. package/dist/dist-esm/react-components/src/components/IncomingCallNotification.js.map +1 -1
  40. package/dist/dist-esm/react-components/src/components/Notification.d.ts +3 -3
  41. package/dist/dist-esm/react-components/src/components/Notification.js +1 -1
  42. package/dist/dist-esm/react-components/src/components/Notification.js.map +1 -1
  43. package/dist/dist-esm/react-components/src/components/NotificationStack.d.ts +5 -5
  44. package/dist/dist-esm/react-components/src/components/NotificationStack.js +1 -1
  45. package/dist/dist-esm/react-components/src/components/NotificationStack.js.map +1 -1
  46. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.d.ts +1 -6
  47. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js +0 -21
  48. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.js.map +1 -1
  49. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/PlaceholderPlugin.js +3 -0
  50. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/PlaceholderPlugin.js.map +1 -1
  51. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js +1 -6
  52. package/dist/dist-esm/react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.js.map +1 -1
  53. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js +2 -8
  54. package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextSendBox.js.map +1 -1
  55. package/dist/dist-esm/react-components/src/components/styles/AttachmentCard.styles.d.ts +1 -1
  56. package/dist/dist-esm/react-components/src/components/styles/MessageThread.styles.d.ts +3 -3
  57. package/dist/dist-esm/react-components/src/components/styles/MessageThread.styles.js +42 -36
  58. package/dist/dist-esm/react-components/src/components/styles/MessageThread.styles.js.map +1 -1
  59. package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js +1 -1
  60. package/dist/dist-esm/react-components/src/components/utils/SendBoxUtils.js.map +1 -1
  61. package/dist/dist-esm/react-composites/src/composites/CallComposite/CallComposite.js +29 -17
  62. package/dist/dist-esm/react-composites/src/composites/CallComposite/CallComposite.js.map +1 -1
  63. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.js +1 -1
  64. package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.js.map +1 -1
  65. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js +19 -28
  66. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ChatScreen.js.map +1 -1
  67. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ImageUpload/ImageUploadUtils.d.ts +12 -0
  68. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ImageUpload/ImageUploadUtils.js +53 -0
  69. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ImageUpload/ImageUploadUtils.js.map +1 -0
  70. package/dist/dist-esm/react-composites/src/composites/ChatComposite/{image-upload → ImageUpload}/useImageUpload.js +7 -21
  71. package/dist/dist-esm/react-composites/src/composites/ChatComposite/ImageUpload/useImageUpload.js.map +1 -0
  72. package/dist/dist-esm/react-composites/src/composites/common/ParticipantContainer.js +9 -5
  73. package/dist/dist-esm/react-composites/src/composites/common/ParticipantContainer.js.map +1 -1
  74. package/package.json +1 -1
  75. package/dist/dist-cjs/communication-react/index-B2uDEMiK.js.map +0 -1
  76. package/dist/dist-esm/react-composites/src/composites/ChatComposite/image-upload/useImageUpload.js.map +0 -1
  77. /package/dist/dist-esm/react-composites/src/composites/ChatComposite/{image-upload → ImageUpload}/useImageUpload.d.ts +0 -0
@@ -3,7 +3,7 @@ import { IIconProps } from '@fluentui/react';
3
3
  /**
4
4
  * Props for {@link Notification}.
5
5
  *
6
- * @beta
6
+ * @public
7
7
  */
8
8
  export interface NotificationProps {
9
9
  /**
@@ -40,7 +40,7 @@ export interface NotificationProps {
40
40
  /**
41
41
  * All strings that may be shown on the UI in the {@link Notification}.
42
42
  *
43
- * @beta
43
+ * @public
44
44
  */
45
45
  export interface NotificationStrings {
46
46
  /**
@@ -67,7 +67,7 @@ export interface NotificationStrings {
67
67
  /**
68
68
  * A component to show notification messages on the UI.
69
69
  *
70
- * @beta
70
+ * @public
71
71
  */
72
72
  export declare const Notification: (props: NotificationProps) => JSX.Element;
73
73
  //# sourceMappingURL=Notification.d.ts.map
@@ -7,7 +7,7 @@ import { containerStyles, hiddenContainerStyles, messageTextStyle, notificationI
7
7
  /**
8
8
  * A component to show notification messages on the UI.
9
9
  *
10
- * @beta
10
+ * @public
11
11
  */
12
12
  export const Notification = (props) => {
13
13
  var _a, _b;
@@ -1 +1 @@
1
- {"version":3,"file":"Notification.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/Notification.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAc,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACpH,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,yBAAyB,EACzB,kBAAkB,EACnB,MAAM,8BAA8B,CAAC;AA0EtC;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAwB,EAAe,EAAE;;IACpE,MAAM,OAAO,GAAG,KAAK,CAAC,mBAAmB,CAAC;IAC1C,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAEvC,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,UAAU,CAAC,GAAG,EAAE;YACd,8CAA8C;YAC9C,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACrC,OAAO,yCAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,CACL,oBAAC,KAAK,IAAC,eAAe,EAAC,QAAQ;QAC7B,oBAAC,KAAK,kBAAY,kBAAkB,EAAC,SAAS,EAAE,eAAe,CAAC,KAAK,CAAC;YACpE,oBAAC,KAAK,IAAC,UAAU,QAAC,eAAe,EAAC,eAAe;gBAC/C,oBAAC,KAAK,IAAC,UAAU;oBACf,oBAAC,IAAI,kBACH,SAAS,EAAE,yBAAyB,EACpC,QAAQ,EAAE,MAAA,MAAA,KAAK,CAAC,qBAAqB,0CAAE,QAAQ,mCAAI,YAAY,IAC3D,KAAK,CAAC,qBAAqB,EAC/B;oBACF,oBAAC,IAAI,IAAC,SAAS,EAAE,kBAAkB,IAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK,CAAQ,CACtD;gBAER,oBAAC,UAAU,IACT,SAAS,EAAE,UAAU,EACrB,SAAS,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,sBAAsB,eAC/B,QAAQ,EACnB,OAAO,EAAE,KAAK,CAAC,SAAS,GACxB,CACI;YACR,oBAAC,IAAI,IAAC,SAAS,EAAE,gBAAgB,CAAC,KAAK,CAAC,IAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAQ;YACnE,oBAAC,KAAK,IAAC,UAAU,QAAC,eAAe,EAAC,cAAc;gBAC7C,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,KAAI,CAChC,oBAAC,aAAa,IAAC,OAAO,EAAE,KAAK,CAAC,sBAAsB,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAC/E,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,CAChB,CACjB;gBACA,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,kBAAkB,KAAI,CAC9B,oBAAC,aAAa,IAAC,OAAO,EAAE,KAAK,CAAC,oBAAoB,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAC7E,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,kBAAkB,CACd,CACjB,CACK,CACF;QACP,KAAK,CAAC,iBAAiB,IAAI,oBAAC,KAAK,IAAC,SAAS,EAAE,qBAAqB,CAAC,KAAK,CAAC,GAAU,CAC9E,CACT,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useState } from 'react';\nimport { Icon, IconButton, PrimaryButton, Stack, useTheme, Text, IIconProps, DefaultButton } from '@fluentui/react';\nimport { cancelIcon } from './styles/ImageOverlay.style';\nimport {\n containerStyles,\n hiddenContainerStyles,\n messageTextStyle,\n notificationIconClassName,\n titleTextClassName\n} from './styles/Notification.styles';\n\n/**\n * Props for {@link Notification}.\n *\n * @beta\n */\nexport interface NotificationProps {\n /**\n * Notification bar strings;\n */\n notificationStrings?: NotificationStrings;\n\n /**\n * Notification bar icon;\n */\n notificationIconProps?: IIconProps;\n\n /**\n * If set, notifications will automatically dismiss after 5 seconds\n * @defaultValue false\n */\n autoDismiss?: boolean;\n\n /**\n * If set, notifications will be shown in a stacked effect\n * @defaultValue false\n */\n showStackedEffect?: boolean;\n\n /**\n * Callback called when the primary button inside notification bar is clicked.\n */\n onClickPrimaryButton?: () => void;\n\n /**\n * Callback called when the secondary button inside notification bar is clicked.\n */\n onClickSecondaryButton?: () => void;\n\n /**\n * Callback called when the notification is dismissed.\n */\n onDismiss?: () => void;\n}\n\n/**\n * All strings that may be shown on the UI in the {@link Notification}.\n *\n * @beta\n */\nexport interface NotificationStrings {\n /**\n * Notification bar title.\n */\n title: string;\n /**\n * Notification bar dismiss button aria label\n */\n dismissButtonAriaLabel: string;\n /**\n * Notification bar message.\n */\n message?: string;\n /**\n * Notification bar primary button label\n */\n primaryButtonLabel?: string;\n /**\n * Notification bar secondary button label\n */\n secondaryButtonLabel?: string;\n}\n\n/**\n * A component to show notification messages on the UI.\n *\n * @beta\n */\nexport const Notification = (props: NotificationProps): JSX.Element => {\n const strings = props.notificationStrings;\n const theme = useTheme();\n const [show, setShow] = useState(true);\n\n if (props.autoDismiss) {\n setTimeout(() => {\n // After 5 seconds set the show value to false\n setShow(false);\n }, 5000);\n\n if (!show) {\n props.onDismiss && props.onDismiss();\n return <></>;\n }\n }\n\n return (\n <Stack horizontalAlign=\"center\">\n <Stack data-ui-id=\"notification-bar\" className={containerStyles(theme)}>\n <Stack horizontal horizontalAlign=\"space-between\">\n <Stack horizontal>\n <Icon\n className={notificationIconClassName}\n iconName={props.notificationIconProps?.iconName ?? 'ErrorBadge'}\n {...props.notificationIconProps}\n />\n <Text className={titleTextClassName}>{strings?.title}</Text>\n </Stack>\n\n <IconButton\n iconProps={cancelIcon}\n ariaLabel={strings?.dismissButtonAriaLabel}\n aria-live={'polite'}\n onClick={props.onDismiss}\n />\n </Stack>\n <Text className={messageTextStyle(theme)}>{strings?.message}</Text>\n <Stack horizontal horizontalAlign=\"space-evenly\">\n {strings?.secondaryButtonLabel && (\n <DefaultButton onClick={props.onClickSecondaryButton} style={{ marginTop: '1rem' }}>\n {strings?.secondaryButtonLabel}\n </DefaultButton>\n )}\n {strings?.primaryButtonLabel && (\n <PrimaryButton onClick={props.onClickPrimaryButton} style={{ marginTop: '1rem' }}>\n {strings?.primaryButtonLabel}\n </PrimaryButton>\n )}\n </Stack>\n </Stack>\n {props.showStackedEffect && <Stack className={hiddenContainerStyles(theme)}></Stack>}\n </Stack>\n );\n};\n"]}
1
+ {"version":3,"file":"Notification.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/Notification.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useState } from 'react';\nimport { Icon, IconButton, PrimaryButton, Stack, useTheme, Text, IIconProps, DefaultButton } from '@fluentui/react';\nimport { cancelIcon } from './styles/ImageOverlay.style';\nimport {\n containerStyles,\n hiddenContainerStyles,\n messageTextStyle,\n notificationIconClassName,\n titleTextClassName\n} from './styles/Notification.styles';\n\n/**\n * Props for {@link Notification}.\n *\n * @public\n */\nexport interface NotificationProps {\n /**\n * Notification bar strings;\n */\n notificationStrings?: NotificationStrings;\n\n /**\n * Notification bar icon;\n */\n notificationIconProps?: IIconProps;\n\n /**\n * If set, notifications will automatically dismiss after 5 seconds\n * @defaultValue false\n */\n autoDismiss?: boolean;\n\n /**\n * If set, notifications will be shown in a stacked effect\n * @defaultValue false\n */\n showStackedEffect?: boolean;\n\n /**\n * Callback called when the primary button inside notification bar is clicked.\n */\n onClickPrimaryButton?: () => void;\n\n /**\n * Callback called when the secondary button inside notification bar is clicked.\n */\n onClickSecondaryButton?: () => void;\n\n /**\n * Callback called when the notification is dismissed.\n */\n onDismiss?: () => void;\n}\n\n/**\n * All strings that may be shown on the UI in the {@link Notification}.\n *\n * @public\n */\nexport interface NotificationStrings {\n /**\n * Notification bar title.\n */\n title: string;\n /**\n * Notification bar dismiss button aria label\n */\n dismissButtonAriaLabel: string;\n /**\n * Notification bar message.\n */\n message?: string;\n /**\n * Notification bar primary button label\n */\n primaryButtonLabel?: string;\n /**\n * Notification bar secondary button label\n */\n secondaryButtonLabel?: string;\n}\n\n/**\n * A component to show notification messages on the UI.\n *\n * @public\n */\nexport const Notification = (props: NotificationProps): JSX.Element => {\n const strings = props.notificationStrings;\n const theme = useTheme();\n const [show, setShow] = useState(true);\n\n if (props.autoDismiss) {\n setTimeout(() => {\n // After 5 seconds set the show value to false\n setShow(false);\n }, 5000);\n\n if (!show) {\n props.onDismiss && props.onDismiss();\n return <></>;\n }\n }\n\n return (\n <Stack horizontalAlign=\"center\">\n <Stack data-ui-id=\"notification-bar\" className={containerStyles(theme)}>\n <Stack horizontal horizontalAlign=\"space-between\">\n <Stack horizontal>\n <Icon\n className={notificationIconClassName}\n iconName={props.notificationIconProps?.iconName ?? 'ErrorBadge'}\n {...props.notificationIconProps}\n />\n <Text className={titleTextClassName}>{strings?.title}</Text>\n </Stack>\n\n <IconButton\n iconProps={cancelIcon}\n ariaLabel={strings?.dismissButtonAriaLabel}\n aria-live={'polite'}\n onClick={props.onDismiss}\n />\n </Stack>\n <Text className={messageTextStyle(theme)}>{strings?.message}</Text>\n <Stack horizontal horizontalAlign=\"space-evenly\">\n {strings?.secondaryButtonLabel && (\n <DefaultButton onClick={props.onClickSecondaryButton} style={{ marginTop: '1rem' }}>\n {strings?.secondaryButtonLabel}\n </DefaultButton>\n )}\n {strings?.primaryButtonLabel && (\n <PrimaryButton onClick={props.onClickPrimaryButton} style={{ marginTop: '1rem' }}>\n {strings?.primaryButtonLabel}\n </PrimaryButton>\n )}\n </Stack>\n </Stack>\n {props.showStackedEffect && <Stack className={hiddenContainerStyles(theme)}></Stack>}\n </Stack>\n );\n};\n"]}
@@ -2,7 +2,7 @@
2
2
  import { NotificationStrings } from './Notification';
3
3
  /**
4
4
  * Props for {@link NotificationStack}.
5
- * @beta
5
+ * @public
6
6
  */
7
7
  export interface NotificationStackProps {
8
8
  /**
@@ -38,7 +38,7 @@ export interface NotificationStackProps {
38
38
  /**
39
39
  * All strings that may be shown on the UI in the {@link NotificationStack}.
40
40
  *
41
- * @beta
41
+ * @public
42
42
  */
43
43
  export interface NotificationStackStrings {
44
44
  /**
@@ -205,13 +205,13 @@ export interface NotificationStackStrings {
205
205
  /**
206
206
  * All notifications that can be shown in the {@link NotificationStack}.
207
207
  *
208
- * @beta
208
+ * @public
209
209
  */
210
210
  export type NotificationType = keyof NotificationStackStrings;
211
211
  /**
212
212
  * Active notifications to be shown via {@link NotificationStack}.
213
213
  *
214
- * @beta
214
+ * @public
215
215
  */
216
216
  export interface ActiveNotification {
217
217
  /**
@@ -253,7 +253,7 @@ export interface ActiveNotification {
253
253
  * If the notification recurs, it is shown in the UI.
254
254
  *
255
255
  *
256
- * @beta
256
+ * @public
257
257
  */
258
258
  export declare const NotificationStack: (props: NotificationStackProps) => JSX.Element;
259
259
  //# sourceMappingURL=NotificationStack.d.ts.map
@@ -17,7 +17,7 @@ import { Notification } from './Notification';
17
17
  * If the notification recurs, it is shown in the UI.
18
18
  *
19
19
  *
20
- * @beta
20
+ * @public
21
21
  */
22
22
  export const NotificationStack = (props) => {
23
23
  var _a, _b;
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationStack.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/NotificationStack.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,gDAAgD;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAEL,qBAAqB,EACrB,mBAAmB,EACnB,sCAAsC,EACtC,mBAAmB,EACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,YAAY,EAAuB,MAAM,gBAAgB,CAAC;AA0RnE;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAA6B,EAAe,EAAE;;IAC9E,gDAAgD;IAChD,MAAM,aAAa,GAAG,SAAS,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC;IAC5D,MAAM,OAAO,GAAG,MAAA,KAAK,CAAC,OAAO,mCAAqD,aAAa,CAAC;IAChG,MAAM,sBAAsB,GAAG,MAAA,KAAK,CAAC,sBAAsB,mCAAI,CAAC,CAAC;IAEjE,MAAM,qCAAqC,GAAG,CAAC,KAAK,CAAC,qBAAqB,CAAC;IAE3E,sDAAsD;IACtD,yDAAyD;IACzD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAEpD,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,GAAG,QAAQ,CAA0B,EAAE,CAAC,CAAC;IAElG,0GAA0G;IAC1G,4EAA4E;IAC5E,SAAS,CAAC,GAAG,EAAE;QACb,qCAAqC;YACnC,yBAAyB,CACvB,sCAAsC,CAAC,KAAK,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,CAC1F,CAAC;IACN,CAAC,EAAE,CAAC,KAAK,CAAC,mBAAmB,EAAE,sBAAsB,EAAE,qCAAqC,CAAC,CAAC,CAAC;IAE/F,MAAM,mBAAmB,GAAG,mBAAmB,CAC7C,KAAK,CAAC,mBAAmB,EACzB,sBAAsB,EACtB,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CACvE,CAAC;IAEF,OAAO,CACL,oBAAC,KAAK,kBACO,qBAAqB,EAChC,KAAK,EAAE;YACL,KAAK,EAAE,aAAa;SACrB,IAEA,mBAAmB,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,KAAK,EAAE,EAAE;QAC/C,IAAI,KAAK,GAAG,sBAAsB,EAAE,CAAC;YACnC,OAAO,CACL,6BAAK,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,GAAG,KAAK,KAAK,sBAAsB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE;gBACjG,oBAAC,YAAY,IACX,mBAAmB,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EACrE,qBAAqB,EAAE,qBAAqB,CAAC,YAAY,CAAC,IAAI,CAAC,EAC/D,oBAAoB,EAAE,GAAG,EAAE,WAAC,OAAA,MAAA,YAAY,CAAC,oBAAoB,4DAAI,CAAA,EAAA,EACjE,sBAAsB,EAAE,GAAG,EAAE,WAAC,OAAA,MAAA,YAAY,CAAC,sBAAsB,4DAAI,CAAA,EAAA,EACrE,SAAS,EAAE,GAAG,EAAE;;wBACd,qCAAqC;4BACnC,CAAC,CAAC,yBAAyB,CAAC,mBAAmB,CAAC,sBAAsB,EAAE,YAAY,CAAC,CAAC;4BACtF,CAAC,CAAC,MAAA,KAAK,CAAC,qBAAqB,sDAAG,YAAY,CAAC,CAAC;wBAChD,YAAY,CAAC,SAAS,IAAI,YAAY,CAAC,SAAS,EAAE,CAAC;oBACrD,CAAC,EACD,iBAAiB,EACf,KAAK,KAAK,sBAAsB,GAAG,CAAC,IAAI,mBAAmB,CAAC,MAAM,GAAG,sBAAsB,EAE7F,WAAW,EAAE,YAAY,CAAC,WAAW,GACrC,CACE,CACP,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,yCAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CACI,CACT,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Stack } from '@fluentui/react';\n/* @conditional-compile-remove(notifications) */\nimport { useLocale } from '../localization';\nimport {\n DismissedNotification,\n NotificationIconProps,\n dismissNotification,\n dropDismissalsForInactiveNotifications,\n notificationsToShow\n} from './utils';\nimport { Notification, NotificationStrings } from './Notification';\n\n/**\n * Props for {@link NotificationStack}.\n * @beta\n */\nexport interface NotificationStackProps {\n /**\n * Strings shown on the UI on errors.\n */\n strings?: NotificationStackStrings;\n\n /**\n * Currently active notifications.\n */\n activeNotifications: ActiveNotification[];\n\n /**\n * Max notifications to show at a time.\n * @defaultValue 2\n */\n maxNotificationsToShow?: number;\n\n /**\n * Callback called when the dismiss button is triggered.\n * Use this to control notifications shown when they dismissed by the user.\n * Note this onDismiss function will affect all notifications in the same stack\n */\n onDismissNotification?: (dismissedNotification: ActiveNotification) => void;\n\n /**\n * If set, notifications with {@link ActiveNotification.timestamp} older than the time this component is mounted\n * are not shown.\n *\n * This is useful when using the {@link NotificationStack} with a stateful client that handles more than one call\n * or chat thread. Set this prop to ignore notifications from previous call or chat.\n *\n * @defaultValue false\n */\n ignorePremountNotifications?: boolean;\n}\n\n/**\n * All strings that may be shown on the UI in the {@link NotificationStack}.\n *\n * @beta\n */\nexport interface NotificationStackStrings {\n /**\n * A generic message when starting video fails.\n */\n startVideoGeneric?: NotificationStrings;\n\n /**\n * A generic message when starting video fails.\n */\n stopVideoGeneric?: NotificationStrings;\n\n /**\n * A generic message when muting microphone fails.\n */\n muteGeneric?: NotificationStrings;\n\n /**\n * A generic message when unmuting microphone fails.\n */\n unmuteGeneric?: NotificationStrings;\n\n /**\n * A generic message when starting screenshare fails.\n */\n startScreenShareGeneric?: NotificationStrings;\n\n /**\n * A generic message when stopping screenshare fails.\n */\n stopScreenShareGeneric?: NotificationStrings;\n\n /**\n * Message shown when poor network quality is detected during a call.\n */\n callNetworkQualityLow?: NotificationStrings;\n /* @conditional-compile-remove(teams-meeting-conference) */\n /**\n * Message shown when poor network quality is detected during a teams meetings.\n * Contains actions to open phone info modal.\n */\n teamsMeetingCallNetworkQualityLow?: NotificationStrings;\n /**\n * Message shown on failure to detect audio output devices.\n */\n callNoSpeakerFound?: NotificationStrings;\n\n /**\n * Message shown on failure to detect audio input devices.\n */\n callNoMicrophoneFound?: NotificationStrings;\n\n /**\n * Message shown when microphone can be enumerated but access is blocked by the system.\n */\n callMicrophoneAccessDenied?: NotificationStrings;\n\n /**\n * Message shown when microphone can be enumerated but access is blocked by the system, for safari browsers\n */\n callMicrophoneAccessDeniedSafari?: NotificationStrings;\n\n /**\n * Message shown when microphone is muted by the system (not by local or remote participants)\n */\n callMicrophoneMutedBySystem?: NotificationStrings;\n\n /**\n * Message shown when microphone is unmuted by the system (not by local or remote participants).\n * This typically occurs if the system recovers from an unexpected mute.\n */\n callMicrophoneUnmutedBySystem?: NotificationStrings;\n\n /**\n * Mac OS specific message shown when microphone can be enumerated but access is\n * blocked by the system.\n */\n callMacOsMicrophoneAccessDenied?: NotificationStrings;\n\n /**\n * Message shown when poor network causes local video stream to be frozen.\n */\n callLocalVideoFreeze?: NotificationStrings;\n\n /**\n * Message shown when camera can be enumerated but access is blocked by the system.\n */\n callCameraAccessDenied?: NotificationStrings;\n\n /**\n * Message shown when camera can be enumerated but access is blocked by the system, for safari browsers\n */\n callCameraAccessDeniedSafari?: NotificationStrings;\n\n /**\n * Message shown when local video fails to start because camera is already in use by\n * another applciation.\n */\n callCameraAlreadyInUse?: NotificationStrings;\n\n /**\n * Message shown when local video is stopped by the system (not by local or remote participants)\n */\n callVideoStoppedBySystem?: NotificationStrings;\n\n /**\n * Message shown when local video was recovered by the system (not by the local participant)\n */\n callVideoRecoveredBySystem?: NotificationStrings;\n\n /**\n * Mac OS specific message shown when system denies access to camera.\n */\n callMacOsCameraAccessDenied?: NotificationStrings;\n\n /**\n * Mac OS specific message shown when system denies sharing local screen on a call.\n */\n callMacOsScreenShareAccessDenied?: NotificationStrings;\n\n /**\n * Dimiss Notifications button aria label read by screen reader accessibility tools\n */\n dismissButtonAriaLabel?: NotificationStrings;\n\n /**\n * An error message when joining a call fails.\n */\n failedToJoinCallGeneric?: NotificationStrings;\n\n /**\n * An error message when joining a call fails specifically due to an invalid meeting link.\n */\n failedToJoinCallInvalidMeetingLink?: NotificationStrings;\n /**\n * Error string letting you know remote participants see a frozen stream for you.\n */\n cameraFrozenForRemoteParticipants?: NotificationStrings;\n\n /**\n * Unable to start effect\n */\n unableToStartVideoEffect?: NotificationStrings;\n /**\n * An error message when starting spotlight while max participants are spotlighted\n */\n startSpotlightWhileMaxParticipantsAreSpotlighted?: NotificationStrings;\n /* @conditional-compile-remove(soft-mute) */\n /**\n * Muted by a remote participant message\n */\n mutedByRemoteParticipant?: NotificationStrings;\n /**\n * Speaking while muted message\n */\n speakingWhileMuted?: NotificationStrings;\n /**\n * Recording started message\n */\n recordingStarted?: NotificationStrings;\n /**\n * Transcription started message\n */\n transcriptionStarted?: NotificationStrings;\n /**\n * Recording stopped message\n */\n recordingStopped?: NotificationStrings;\n /**\n * Transcription stopped message\n */\n transcriptionStopped?: NotificationStrings;\n /**\n * Recording and transcription both started message\n */\n recordingAndTranscriptionStarted?: NotificationStrings;\n /**\n * Recording and transcription both stopped message\n */\n recordingAndTranscriptionStopped?: NotificationStrings;\n /**\n * Recording stopped but transcription still going on message\n */\n recordingStoppedStillTranscribing?: NotificationStrings;\n /**\n * Transcription stopped but recording still going on message\n */\n transcriptionStoppedStillRecording?: NotificationStrings;\n}\n\n/**\n * All notifications that can be shown in the {@link NotificationStack}.\n *\n * @beta\n */\nexport type NotificationType = keyof NotificationStackStrings;\n\n/**\n * Active notifications to be shown via {@link NotificationStack}.\n *\n * @beta\n */\nexport interface ActiveNotification {\n /**\n * Type of error that is active.\n */\n type: NotificationType;\n /**\n * Callback called when the primary button inside notification bar is clicked.\n */\n onClickPrimaryButton?: () => void;\n\n /**\n * Callback called when the primary button inside notification bar is clicked.\n */\n onClickSecondaryButton?: () => void;\n\n /**\n * Callback called when the notification is dismissed.\n */\n onDismiss?: () => void;\n\n /**\n * If set, notification will automatically dismiss after 5 seconds\n */\n autoDismiss?: boolean;\n\n /**\n * The latest timestamp when this notification was observed.\n *\n * When available, this is used to track notifications that have already been seen and dismissed\n * by the user.\n */\n timestamp?: Date;\n}\n\n/**\n * A component to show notifications on the UI.\n * All strings that can be shown are accepted as the {@link NotificationStackProps.strings} so that they can be localized.\n * Active notifications are selected by {@link NotificationStackProps.activeNotifications}.\n *\n * This component internally tracks dismissed by the user.\n * * Notifications that have an associated timestamp: The notification is shown on the UI again if it occurs after being dismissed.\n * * Notifications that do not have a timestamp: The notification is dismissed until it disappears from the props.\n * If the notification recurs, it is shown in the UI.\n *\n *\n * @beta\n */\nexport const NotificationStack = (props: NotificationStackProps): JSX.Element => {\n /* @conditional-compile-remove(notifications) */\n const localeStrings = useLocale().strings.notificationStack;\n const strings = props.strings ?? /* @conditional-compile-remove(notifications) */ localeStrings;\n const maxNotificationsToShow = props.maxNotificationsToShow ?? 2;\n\n const trackDismissedNotificationsInternally = !props.onDismissNotification;\n\n // Timestamp for when this comopnent is first mounted.\n // Never updated through the lifecycle of this component.\n const mountTimestamp = useRef(new Date(Date.now()));\n\n const [dismissedNotifications, setDismissedNotifications] = useState<DismissedNotification[]>([]);\n\n // dropDismissalsForInactiveNotifications only returns a new object if `dismissedErrors` actually changes.\n // Without this behaviour, this `useEffect` block would cause a render loop.\n useEffect(() => {\n trackDismissedNotificationsInternally &&\n setDismissedNotifications(\n dropDismissalsForInactiveNotifications(props.activeNotifications, dismissedNotifications)\n );\n }, [props.activeNotifications, dismissedNotifications, trackDismissedNotificationsInternally]);\n\n const activeNotifications = notificationsToShow(\n props.activeNotifications,\n dismissedNotifications,\n props.ignorePremountNotifications ? mountTimestamp.current : undefined\n );\n\n return (\n <Stack\n data-ui-id=\"notifications-stack\"\n style={{\n width: 'fit-content'\n }}\n >\n {activeNotifications.map((notification, index) => {\n if (index < maxNotificationsToShow) {\n return (\n <div key={index} style={{ marginBottom: `${index === maxNotificationsToShow - 1 ? 0 : '0.25rem'}` }}>\n <Notification\n notificationStrings={strings ? strings[notification.type] : undefined}\n notificationIconProps={NotificationIconProps(notification.type)}\n onClickPrimaryButton={() => notification.onClickPrimaryButton?.()}\n onClickSecondaryButton={() => notification.onClickSecondaryButton?.()}\n onDismiss={() => {\n trackDismissedNotificationsInternally\n ? setDismissedNotifications(dismissNotification(dismissedNotifications, notification))\n : props.onDismissNotification?.(notification);\n notification.onDismiss && notification.onDismiss();\n }}\n showStackedEffect={\n index === maxNotificationsToShow - 1 && activeNotifications.length > maxNotificationsToShow\n }\n autoDismiss={notification.autoDismiss}\n />\n </div>\n );\n } else {\n return <></>;\n }\n })}\n </Stack>\n );\n};\n"]}
1
+ {"version":3,"file":"NotificationStack.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/NotificationStack.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { Stack } from '@fluentui/react';\n/* @conditional-compile-remove(notifications) */\nimport { useLocale } from '../localization';\nimport {\n DismissedNotification,\n NotificationIconProps,\n dismissNotification,\n dropDismissalsForInactiveNotifications,\n notificationsToShow\n} from './utils';\nimport { Notification, NotificationStrings } from './Notification';\n\n/**\n * Props for {@link NotificationStack}.\n * @public\n */\nexport interface NotificationStackProps {\n /**\n * Strings shown on the UI on errors.\n */\n strings?: NotificationStackStrings;\n\n /**\n * Currently active notifications.\n */\n activeNotifications: ActiveNotification[];\n\n /**\n * Max notifications to show at a time.\n * @defaultValue 2\n */\n maxNotificationsToShow?: number;\n\n /**\n * Callback called when the dismiss button is triggered.\n * Use this to control notifications shown when they dismissed by the user.\n * Note this onDismiss function will affect all notifications in the same stack\n */\n onDismissNotification?: (dismissedNotification: ActiveNotification) => void;\n\n /**\n * If set, notifications with {@link ActiveNotification.timestamp} older than the time this component is mounted\n * are not shown.\n *\n * This is useful when using the {@link NotificationStack} with a stateful client that handles more than one call\n * or chat thread. Set this prop to ignore notifications from previous call or chat.\n *\n * @defaultValue false\n */\n ignorePremountNotifications?: boolean;\n}\n\n/**\n * All strings that may be shown on the UI in the {@link NotificationStack}.\n *\n * @public\n */\nexport interface NotificationStackStrings {\n /**\n * A generic message when starting video fails.\n */\n startVideoGeneric?: NotificationStrings;\n\n /**\n * A generic message when starting video fails.\n */\n stopVideoGeneric?: NotificationStrings;\n\n /**\n * A generic message when muting microphone fails.\n */\n muteGeneric?: NotificationStrings;\n\n /**\n * A generic message when unmuting microphone fails.\n */\n unmuteGeneric?: NotificationStrings;\n\n /**\n * A generic message when starting screenshare fails.\n */\n startScreenShareGeneric?: NotificationStrings;\n\n /**\n * A generic message when stopping screenshare fails.\n */\n stopScreenShareGeneric?: NotificationStrings;\n\n /**\n * Message shown when poor network quality is detected during a call.\n */\n callNetworkQualityLow?: NotificationStrings;\n /* @conditional-compile-remove(teams-meeting-conference) */\n /**\n * Message shown when poor network quality is detected during a teams meetings.\n * Contains actions to open phone info modal.\n */\n teamsMeetingCallNetworkQualityLow?: NotificationStrings;\n /**\n * Message shown on failure to detect audio output devices.\n */\n callNoSpeakerFound?: NotificationStrings;\n\n /**\n * Message shown on failure to detect audio input devices.\n */\n callNoMicrophoneFound?: NotificationStrings;\n\n /**\n * Message shown when microphone can be enumerated but access is blocked by the system.\n */\n callMicrophoneAccessDenied?: NotificationStrings;\n\n /**\n * Message shown when microphone can be enumerated but access is blocked by the system, for safari browsers\n */\n callMicrophoneAccessDeniedSafari?: NotificationStrings;\n\n /**\n * Message shown when microphone is muted by the system (not by local or remote participants)\n */\n callMicrophoneMutedBySystem?: NotificationStrings;\n\n /**\n * Message shown when microphone is unmuted by the system (not by local or remote participants).\n * This typically occurs if the system recovers from an unexpected mute.\n */\n callMicrophoneUnmutedBySystem?: NotificationStrings;\n\n /**\n * Mac OS specific message shown when microphone can be enumerated but access is\n * blocked by the system.\n */\n callMacOsMicrophoneAccessDenied?: NotificationStrings;\n\n /**\n * Message shown when poor network causes local video stream to be frozen.\n */\n callLocalVideoFreeze?: NotificationStrings;\n\n /**\n * Message shown when camera can be enumerated but access is blocked by the system.\n */\n callCameraAccessDenied?: NotificationStrings;\n\n /**\n * Message shown when camera can be enumerated but access is blocked by the system, for safari browsers\n */\n callCameraAccessDeniedSafari?: NotificationStrings;\n\n /**\n * Message shown when local video fails to start because camera is already in use by\n * another applciation.\n */\n callCameraAlreadyInUse?: NotificationStrings;\n\n /**\n * Message shown when local video is stopped by the system (not by local or remote participants)\n */\n callVideoStoppedBySystem?: NotificationStrings;\n\n /**\n * Message shown when local video was recovered by the system (not by the local participant)\n */\n callVideoRecoveredBySystem?: NotificationStrings;\n\n /**\n * Mac OS specific message shown when system denies access to camera.\n */\n callMacOsCameraAccessDenied?: NotificationStrings;\n\n /**\n * Mac OS specific message shown when system denies sharing local screen on a call.\n */\n callMacOsScreenShareAccessDenied?: NotificationStrings;\n\n /**\n * Dimiss Notifications button aria label read by screen reader accessibility tools\n */\n dismissButtonAriaLabel?: NotificationStrings;\n\n /**\n * An error message when joining a call fails.\n */\n failedToJoinCallGeneric?: NotificationStrings;\n\n /**\n * An error message when joining a call fails specifically due to an invalid meeting link.\n */\n failedToJoinCallInvalidMeetingLink?: NotificationStrings;\n /**\n * Error string letting you know remote participants see a frozen stream for you.\n */\n cameraFrozenForRemoteParticipants?: NotificationStrings;\n\n /**\n * Unable to start effect\n */\n unableToStartVideoEffect?: NotificationStrings;\n /**\n * An error message when starting spotlight while max participants are spotlighted\n */\n startSpotlightWhileMaxParticipantsAreSpotlighted?: NotificationStrings;\n /* @conditional-compile-remove(soft-mute) */\n /**\n * Muted by a remote participant message\n */\n mutedByRemoteParticipant?: NotificationStrings;\n /**\n * Speaking while muted message\n */\n speakingWhileMuted?: NotificationStrings;\n /**\n * Recording started message\n */\n recordingStarted?: NotificationStrings;\n /**\n * Transcription started message\n */\n transcriptionStarted?: NotificationStrings;\n /**\n * Recording stopped message\n */\n recordingStopped?: NotificationStrings;\n /**\n * Transcription stopped message\n */\n transcriptionStopped?: NotificationStrings;\n /**\n * Recording and transcription both started message\n */\n recordingAndTranscriptionStarted?: NotificationStrings;\n /**\n * Recording and transcription both stopped message\n */\n recordingAndTranscriptionStopped?: NotificationStrings;\n /**\n * Recording stopped but transcription still going on message\n */\n recordingStoppedStillTranscribing?: NotificationStrings;\n /**\n * Transcription stopped but recording still going on message\n */\n transcriptionStoppedStillRecording?: NotificationStrings;\n}\n\n/**\n * All notifications that can be shown in the {@link NotificationStack}.\n *\n * @public\n */\nexport type NotificationType = keyof NotificationStackStrings;\n\n/**\n * Active notifications to be shown via {@link NotificationStack}.\n *\n * @public\n */\nexport interface ActiveNotification {\n /**\n * Type of error that is active.\n */\n type: NotificationType;\n /**\n * Callback called when the primary button inside notification bar is clicked.\n */\n onClickPrimaryButton?: () => void;\n\n /**\n * Callback called when the primary button inside notification bar is clicked.\n */\n onClickSecondaryButton?: () => void;\n\n /**\n * Callback called when the notification is dismissed.\n */\n onDismiss?: () => void;\n\n /**\n * If set, notification will automatically dismiss after 5 seconds\n */\n autoDismiss?: boolean;\n\n /**\n * The latest timestamp when this notification was observed.\n *\n * When available, this is used to track notifications that have already been seen and dismissed\n * by the user.\n */\n timestamp?: Date;\n}\n\n/**\n * A component to show notifications on the UI.\n * All strings that can be shown are accepted as the {@link NotificationStackProps.strings} so that they can be localized.\n * Active notifications are selected by {@link NotificationStackProps.activeNotifications}.\n *\n * This component internally tracks dismissed by the user.\n * * Notifications that have an associated timestamp: The notification is shown on the UI again if it occurs after being dismissed.\n * * Notifications that do not have a timestamp: The notification is dismissed until it disappears from the props.\n * If the notification recurs, it is shown in the UI.\n *\n *\n * @public\n */\nexport const NotificationStack = (props: NotificationStackProps): JSX.Element => {\n /* @conditional-compile-remove(notifications) */\n const localeStrings = useLocale().strings.notificationStack;\n const strings = props.strings ?? /* @conditional-compile-remove(notifications) */ localeStrings;\n const maxNotificationsToShow = props.maxNotificationsToShow ?? 2;\n\n const trackDismissedNotificationsInternally = !props.onDismissNotification;\n\n // Timestamp for when this comopnent is first mounted.\n // Never updated through the lifecycle of this component.\n const mountTimestamp = useRef(new Date(Date.now()));\n\n const [dismissedNotifications, setDismissedNotifications] = useState<DismissedNotification[]>([]);\n\n // dropDismissalsForInactiveNotifications only returns a new object if `dismissedErrors` actually changes.\n // Without this behaviour, this `useEffect` block would cause a render loop.\n useEffect(() => {\n trackDismissedNotificationsInternally &&\n setDismissedNotifications(\n dropDismissalsForInactiveNotifications(props.activeNotifications, dismissedNotifications)\n );\n }, [props.activeNotifications, dismissedNotifications, trackDismissedNotificationsInternally]);\n\n const activeNotifications = notificationsToShow(\n props.activeNotifications,\n dismissedNotifications,\n props.ignorePremountNotifications ? mountTimestamp.current : undefined\n );\n\n return (\n <Stack\n data-ui-id=\"notifications-stack\"\n style={{\n width: 'fit-content'\n }}\n >\n {activeNotifications.map((notification, index) => {\n if (index < maxNotificationsToShow) {\n return (\n <div key={index} style={{ marginBottom: `${index === maxNotificationsToShow - 1 ? 0 : '0.25rem'}` }}>\n <Notification\n notificationStrings={strings ? strings[notification.type] : undefined}\n notificationIconProps={NotificationIconProps(notification.type)}\n onClickPrimaryButton={() => notification.onClickPrimaryButton?.()}\n onClickSecondaryButton={() => notification.onClickSecondaryButton?.()}\n onDismiss={() => {\n trackDismissedNotificationsInternally\n ? setDismissedNotifications(dismissNotification(dismissedNotifications, notification))\n : props.onDismissNotification?.(notification);\n notification.onDismiss && notification.onDismiss();\n }}\n showStackedEffect={\n index === maxNotificationsToShow - 1 && activeNotifications.length > maxNotificationsToShow\n }\n autoDismiss={notification.autoDismiss}\n />\n </div>\n );\n } else {\n return <></>;\n }\n })}\n </Stack>\n );\n};\n"]}
@@ -1,4 +1,4 @@
1
- import type { PluginEvent, EditorPlugin, IEditor, BeforePasteEvent } from 'roosterjs-content-model-types';
1
+ import type { PluginEvent, EditorPlugin, IEditor } from 'roosterjs-content-model-types';
2
2
  /**
3
3
  * CopyPastePlugin is a plugin for handling copy and paste events in the editor.
4
4
  */
@@ -25,11 +25,6 @@ export declare const handleBeforePasteEvent: (event: PluginEvent, onPaste?: (eve
25
25
  * Exported only for unit testing
26
26
  */
27
27
  export declare const handleInlineImage: (event: PluginEvent, onUploadInlineImage?: (image: string, fileName: string) => void) => void;
28
- /**
29
- * @internal
30
- * Exported only for unit testing
31
- */
32
- export declare const removeImageElement: (event: BeforePasteEvent) => void;
33
28
  /**
34
29
  * Update the scroll position of the editor after pasting content to ensure the content is visible.
35
30
  * @param event - The plugin event.
@@ -36,9 +36,6 @@ export const handleBeforePasteEvent = (event,
36
36
  onPaste === null || onPaste === void 0 ? void 0 : onPaste({ content: event.fragment });
37
37
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
38
38
  return;
39
- // the initial behavior
40
- // removes inline image elements from the pasted content when rich-text-editor-image-upload not available
41
- removeImageElement(event);
42
39
  }
43
40
  };
44
41
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
@@ -64,24 +61,6 @@ export const handleInlineImage = (event, onUploadInlineImage) => {
64
61
  });
65
62
  }
66
63
  };
67
- /**
68
- * @internal
69
- * Exported only for unit testing
70
- */
71
- export const removeImageElement = (event) => {
72
- if (event.pasteType === 'normal') {
73
- event.fragment.querySelectorAll('img').forEach((image) => {
74
- // If the image is the only child of its parent, remove all the parents of this img element.
75
- let parentNode = image.parentElement;
76
- let currentNode = image;
77
- while ((parentNode === null || parentNode === void 0 ? void 0 : parentNode.childNodes.length) === 1) {
78
- currentNode = parentNode;
79
- parentNode = parentNode.parentElement;
80
- }
81
- currentNode === null || currentNode === void 0 ? void 0 : currentNode.remove();
82
- });
83
- }
84
- };
85
64
  /**
86
65
  * Update the scroll position of the editor after pasting content to ensure the content is visible.
87
66
  * @param event - The plugin event.
@@ -1 +1 @@
1
- {"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport type { PluginEvent, EditorPlugin, IEditor, BeforePasteEvent } from 'roosterjs-content-model-types';\nimport { ContentChangedEventSource, PluginEventType } from '../../utils/RichTextEditorUtils';\n/* @conditional-compile-remove(rich-text-editor-image-upload) */\nimport { _base64ToBlob } from '@internal/acs-ui-common';\n\n/**\n * CopyPastePlugin is a plugin for handling copy and paste events in the editor.\n */\nexport default class CopyPastePlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n // don't set value in constructor to be able to update it without plugin recreation\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onPaste?: (event: { content: DocumentFragment }) => void;\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onUploadInlineImage?: (imageUrl: string, imageFileName: string) => void;\n\n getName(): string {\n return 'CopyPastePlugin';\n }\n\n initialize(editor: IEditor): void {\n this.editor = editor;\n }\n\n dispose(): void {}\n\n onPluginEvent(event: PluginEvent): void {\n handleBeforePasteEvent(event, /* @conditional-compile-remove(rich-text-editor-image-upload) */ this.onPaste);\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n handleInlineImage(event, this.onUploadInlineImage);\n if (this.editor !== null && !this.editor.isDisposed()) {\n // scroll the editor to the correct position after pasting content\n scrollToBottomAfterContentPaste(event);\n }\n }\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const handleBeforePasteEvent = (\n event: PluginEvent,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ onPaste?: (event: {\n content: DocumentFragment;\n }) => void\n): void => {\n if (event.eventType === PluginEventType.BeforePaste && event.pasteType === 'normal') {\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onPaste?.({ content: event.fragment });\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n return;\n\n // the initial behavior\n // removes inline image elements from the pasted content when rich-text-editor-image-upload not available\n removeImageElement(event as BeforePasteEvent);\n }\n};\n\n/* @conditional-compile-remove(rich-text-editor-image-upload) */\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const handleInlineImage = (\n event: PluginEvent,\n onUploadInlineImage?: (image: string, fileName: string) => void\n): void => {\n if (event.eventType === PluginEventType.BeforePaste && event.pasteType === 'normal' && onUploadInlineImage) {\n event.fragment.querySelectorAll('img').forEach((image) => {\n const clipboardImage = event.clipboardData.image;\n const fileName = clipboardImage?.name || clipboardImage?.type.replace('/', '.') || 'image.png';\n // If the image src is an external url, call the onUploadInlineImage callback with the url.\n let imageUrl = image.src;\n if (image.src.startsWith('data:image/')) {\n const blobImage = _base64ToBlob(image.src);\n imageUrl = URL.createObjectURL(blobImage);\n }\n\n onUploadInlineImage(imageUrl, fileName);\n\n image.src = imageUrl;\n image.alt = image.alt || 'image';\n image.style.width = '119px'; // TODO: find a way to get the original width and height of the image\n });\n }\n};\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const removeImageElement = (event: BeforePasteEvent): void => {\n if (event.pasteType === 'normal') {\n event.fragment.querySelectorAll('img').forEach((image) => {\n // If the image is the only child of its parent, remove all the parents of this img element.\n let parentNode: HTMLElement | null = image.parentElement;\n let currentNode: HTMLElement = image;\n while (parentNode?.childNodes.length === 1) {\n currentNode = parentNode;\n parentNode = parentNode.parentElement;\n }\n currentNode?.remove();\n });\n }\n};\n\n/**\n * Update the scroll position of the editor after pasting content to ensure the content is visible.\n * @param event - The plugin event.\n */\nexport const scrollToBottomAfterContentPaste = (event: PluginEvent): void => {\n if (event.eventType === PluginEventType.ContentChanged && event.source === ContentChangedEventSource.Paste) {\n // Get the current selection in the document\n const selection = document.getSelection();\n\n // Check if a selection exists and it has at least one range\n if (!selection || selection.rangeCount <= 0) {\n // If no selection or range, exit the function\n return;\n }\n\n // Get the first range of the selection\n // A user can normally only select one range at a time, so the rangeCount will usually be 1\n const range = selection.getRangeAt(0);\n\n // If the common ancestor container of the range is the document itself,\n // it might mean that the editable element is getting removed from the DOM\n // In such cases, especially in Safari, trying to modify the range might throw a HierarchyRequest error\n if (range.commonAncestorContainer === document) {\n return;\n }\n\n // Create a temporary span element to use as an anchor for scrolling\n // We can't use the anchor node directly because if it's a Text node, calling scrollIntoView() on it will throw an error\n const tempElement = document.createElement('span');\n // Collapse the range to its end point\n // This means the start and end points of the range will be the same, and it will not contain any content\n range.collapse(false);\n // Insert the temporary element at the cursor's position at the end of the range\n range.insertNode(tempElement);\n\n // Scroll the temporary element into view\n // the element will be aligned at the center of the scroll container, otherwise, text and images may be positioned incorrectly\n tempElement.scrollIntoView({\n block: 'center'\n });\n tempElement.remove();\n }\n};\n"]}
1
+ {"version":3,"file":"CopyPastePlugin.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/CopyPastePlugin.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport type { PluginEvent, EditorPlugin, IEditor } from 'roosterjs-content-model-types';\nimport { ContentChangedEventSource, PluginEventType } from '../../utils/RichTextEditorUtils';\n/* @conditional-compile-remove(rich-text-editor-image-upload) */\nimport { _base64ToBlob } from '@internal/acs-ui-common';\n\n/**\n * CopyPastePlugin is a plugin for handling copy and paste events in the editor.\n */\nexport default class CopyPastePlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n // don't set value in constructor to be able to update it without plugin recreation\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onPaste?: (event: { content: DocumentFragment }) => void;\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onUploadInlineImage?: (imageUrl: string, imageFileName: string) => void;\n\n getName(): string {\n return 'CopyPastePlugin';\n }\n\n initialize(editor: IEditor): void {\n this.editor = editor;\n }\n\n dispose(): void {}\n\n onPluginEvent(event: PluginEvent): void {\n handleBeforePasteEvent(event, /* @conditional-compile-remove(rich-text-editor-image-upload) */ this.onPaste);\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n handleInlineImage(event, this.onUploadInlineImage);\n if (this.editor !== null && !this.editor.isDisposed()) {\n // scroll the editor to the correct position after pasting content\n scrollToBottomAfterContentPaste(event);\n }\n }\n}\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const handleBeforePasteEvent = (\n event: PluginEvent,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ onPaste?: (event: {\n content: DocumentFragment;\n }) => void\n): void => {\n if (event.eventType === PluginEventType.BeforePaste && event.pasteType === 'normal') {\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onPaste?.({ content: event.fragment });\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n return;\n }\n};\n\n/* @conditional-compile-remove(rich-text-editor-image-upload) */\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const handleInlineImage = (\n event: PluginEvent,\n onUploadInlineImage?: (image: string, fileName: string) => void\n): void => {\n if (event.eventType === PluginEventType.BeforePaste && event.pasteType === 'normal' && onUploadInlineImage) {\n event.fragment.querySelectorAll('img').forEach((image) => {\n const clipboardImage = event.clipboardData.image;\n const fileName = clipboardImage?.name || clipboardImage?.type.replace('/', '.') || 'image.png';\n // If the image src is an external url, call the onUploadInlineImage callback with the url.\n let imageUrl = image.src;\n if (image.src.startsWith('data:image/')) {\n const blobImage = _base64ToBlob(image.src);\n imageUrl = URL.createObjectURL(blobImage);\n }\n\n onUploadInlineImage(imageUrl, fileName);\n\n image.src = imageUrl;\n image.alt = image.alt || 'image';\n image.style.width = '119px'; // TODO: find a way to get the original width and height of the image\n });\n }\n};\n\n/**\n * Update the scroll position of the editor after pasting content to ensure the content is visible.\n * @param event - The plugin event.\n */\nexport const scrollToBottomAfterContentPaste = (event: PluginEvent): void => {\n if (event.eventType === PluginEventType.ContentChanged && event.source === ContentChangedEventSource.Paste) {\n // Get the current selection in the document\n const selection = document.getSelection();\n\n // Check if a selection exists and it has at least one range\n if (!selection || selection.rangeCount <= 0) {\n // If no selection or range, exit the function\n return;\n }\n\n // Get the first range of the selection\n // A user can normally only select one range at a time, so the rangeCount will usually be 1\n const range = selection.getRangeAt(0);\n\n // If the common ancestor container of the range is the document itself,\n // it might mean that the editable element is getting removed from the DOM\n // In such cases, especially in Safari, trying to modify the range might throw a HierarchyRequest error\n if (range.commonAncestorContainer === document) {\n return;\n }\n\n // Create a temporary span element to use as an anchor for scrolling\n // We can't use the anchor node directly because if it's a Text node, calling scrollIntoView() on it will throw an error\n const tempElement = document.createElement('span');\n // Collapse the range to its end point\n // This means the start and end points of the range will be the same, and it will not contain any content\n range.collapse(false);\n // Insert the temporary element at the cursor's position at the end of the range\n range.insertNode(tempElement);\n\n // Scroll the temporary element into view\n // the element will be aligned at the center of the scroll container, otherwise, text and images may be positioned incorrectly\n tempElement.scrollIntoView({\n block: 'center'\n });\n tempElement.remove();\n }\n};\n"]}
@@ -22,6 +22,9 @@ export class PlaceholderPlugin extends WatermarkPlugin {
22
22
  initialize(editor) {
23
23
  this.editorValue = editor;
24
24
  super.initialize(editor);
25
+ // Hide/show the placeholder as workaround for the placeholder not hiding in some cases
26
+ this.hide(this.editorValue);
27
+ this.show(this.editorValue);
25
28
  }
26
29
  dispose() {
27
30
  this.editorValue = null;
@@ -1 +1 @@
1
- {"version":3,"file":"PlaceholderPlugin.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/PlaceholderPlugin.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAGlE;;GAEG;AACH,MAAM,OAAO,iBAAkB,SAAQ,eAAe;IAAtD;;QACU,uBAAkB,GAAY,KAAK,CAAC;QACpC,gBAAW,GAAmB,IAAI,CAAC;IA2B7C,CAAC;IAzBC,iBAAiB,CAAC,WAAmB;QACnC,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC;QAC7B,uDAAuD;QACvD,mEAAmE;QACnE,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,UAAU,CAAC,MAAe;QACxB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC;QAC1B,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO;QACL,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;IACS,IAAI,CAAC,MAAe;QAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;IACjC,CAAC;IACS,IAAI,CAAC,MAAe;QAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;IAClC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { WatermarkPlugin } from 'roosterjs-content-model-plugins';\nimport type { IEditor } from 'roosterjs-content-model-types';\n\n/**\n * PlaceholderPlugin is a plugin for displaying placeholder and handle localization for it in the editor.\n */\nexport class PlaceholderPlugin extends WatermarkPlugin {\n private isPlaceholderShown: boolean = false;\n private editorValue: IEditor | null = null;\n\n updatePlaceholder(placeholder: string): void {\n this.watermark = placeholder;\n // hide and show the placeholder to show the latest one\n // this needs to be done only if the placeholder is currently shown\n if (this.editorValue && this.isPlaceholderShown) {\n this.hide(this.editorValue);\n this.show(this.editorValue);\n }\n }\n initialize(editor: IEditor): void {\n this.editorValue = editor;\n super.initialize(editor);\n }\n dispose(): void {\n this.editorValue = null;\n super.dispose();\n }\n protected show(editor: IEditor): void {\n super.show(editor);\n this.isPlaceholderShown = true;\n }\n protected hide(editor: IEditor): void {\n super.hide(editor);\n this.isPlaceholderShown = false;\n }\n}\n"]}
1
+ {"version":3,"file":"PlaceholderPlugin.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/PlaceholderPlugin.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAGlE;;GAEG;AACH,MAAM,OAAO,iBAAkB,SAAQ,eAAe;IAAtD;;QACU,uBAAkB,GAAY,KAAK,CAAC;QACpC,gBAAW,GAAmB,IAAI,CAAC;IA+B7C,CAAC;IA7BC,iBAAiB,CAAC,WAAmB;QACnC,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC;QAC7B,uDAAuD;QACvD,mEAAmE;QACnE,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,UAAU,CAAC,MAAe;QACxB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC;QAC1B,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAEzB,uFAAuF;QACvF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO;QACL,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;IACS,IAAI,CAAC,MAAe;QAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;IACjC,CAAC;IACS,IAAI,CAAC,MAAe;QAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;IAClC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { WatermarkPlugin } from 'roosterjs-content-model-plugins';\nimport type { IEditor } from 'roosterjs-content-model-types';\n\n/**\n * PlaceholderPlugin is a plugin for displaying placeholder and handle localization for it in the editor.\n */\nexport class PlaceholderPlugin extends WatermarkPlugin {\n private isPlaceholderShown: boolean = false;\n private editorValue: IEditor | null = null;\n\n updatePlaceholder(placeholder: string): void {\n this.watermark = placeholder;\n // hide and show the placeholder to show the latest one\n // this needs to be done only if the placeholder is currently shown\n if (this.editorValue && this.isPlaceholderShown) {\n this.hide(this.editorValue);\n this.show(this.editorValue);\n }\n }\n initialize(editor: IEditor): void {\n this.editorValue = editor;\n super.initialize(editor);\n\n // Hide/show the placeholder as workaround for the placeholder not hiding in some cases\n this.hide(this.editorValue);\n this.show(this.editorValue);\n }\n dispose(): void {\n this.editorValue = null;\n super.dispose();\n }\n protected show(editor: IEditor): void {\n super.show(editor);\n this.isPlaceholderShown = true;\n }\n protected hide(editor: IEditor): void {\n super.hide(editor);\n this.isPlaceholderShown = false;\n }\n}\n"]}
@@ -69,23 +69,18 @@ export class UpdateContentPlugin {
69
69
  case PluginEventType.ContentChanged:
70
70
  if (event.source.toLowerCase() === 'cut' ||
71
71
  (event.source.toLowerCase() === 'keyboard' && (event.data === Keys.BACKSPACE || event.data === Keys.DELETE))) {
72
+ imageSrcArray = [];
72
73
  (_a = event.contentModel) === null || _a === void 0 ? void 0 : _a.blocks.map((block) => {
73
74
  if (block.blockType === 'Paragraph') {
74
75
  const segments = block.segments;
75
76
  segments.map((segment) => {
76
77
  if (segment.segmentType === 'Image') {
77
- if (!imageSrcArray) {
78
- imageSrcArray = [];
79
- }
80
78
  imageSrcArray === null || imageSrcArray === void 0 ? void 0 : imageSrcArray.push(segment.src);
81
79
  }
82
80
  });
83
81
  }
84
82
  });
85
83
  }
86
- else {
87
- imageSrcArray = undefined;
88
- }
89
84
  this.onUpdate(UpdateEvent.ContentChanged, imageSrcArray);
90
85
  break;
91
86
  case PluginEventType.Input:
@@ -1 +1 @@
1
- {"version":3,"file":"UpdateContentPlugin.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';\nimport { PluginEventType } from '../../utils/RichTextEditorUtils';\n\n/**\n * An update mode to indicate when the content update happens\n */\nexport enum UpdateEvent {\n Init = 'Init',\n Dispose = 'Dispose',\n ContentChanged = 'ContentChanged',\n UserInput = 'UserInput',\n Blur = 'Blur'\n}\n\nconst enum Keys {\n BACKSPACE = 8,\n DELETE = 46\n}\n\n/**\n * A plugin to handle content update\n */\nexport class UpdateContentPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n // don't set callback in constructor to be able to update callback without plugin recreation\n onUpdate: ((event: UpdateEvent, imageSrcArray?: Array<string>) => void) | null = null;\n\n getName(): string {\n return 'UpdateContentPlugin';\n }\n\n /**\n * Initialize this plugin\n * @param editor The editor instance\n */\n initialize(editor: IEditor): void {\n this.editor = editor;\n this.disposer = this.editor.attachDomEvent({\n blur: { beforeDispatch: this.onBlur }\n });\n }\n\n dispose(): void {\n this.editor = null;\n\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n }\n\n onPluginEvent(event: PluginEvent): void {\n if (this.onUpdate === null) {\n return;\n }\n let imageSrcArray: Array<string> | undefined;\n\n switch (event.eventType) {\n case PluginEventType.EditorReady:\n this.onUpdate(UpdateEvent.Init);\n break;\n\n case PluginEventType.BeforeDispose:\n this.onUpdate(UpdateEvent.Dispose);\n break;\n\n case PluginEventType.ContentChanged:\n if (\n event.source.toLowerCase() === 'cut' ||\n (event.source.toLowerCase() === 'keyboard' && (event.data === Keys.BACKSPACE || event.data === Keys.DELETE))\n ) {\n event.contentModel?.blocks.map((block) => {\n if (block.blockType === 'Paragraph') {\n const segments = block.segments;\n segments.map((segment) => {\n if (segment.segmentType === 'Image') {\n if (!imageSrcArray) {\n imageSrcArray = [];\n }\n imageSrcArray?.push(segment.src);\n }\n });\n }\n });\n } else {\n imageSrcArray = undefined;\n }\n this.onUpdate(UpdateEvent.ContentChanged, imageSrcArray);\n break;\n\n case PluginEventType.Input:\n this.onUpdate(UpdateEvent.UserInput);\n break;\n }\n }\n\n private onBlur = (): void => {\n if (this.onUpdate === null) {\n return;\n }\n this.onUpdate(UpdateEvent.Blur);\n };\n}\n"]}
1
+ {"version":3,"file":"UpdateContentPlugin.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/RichTextEditor/Plugins/UpdateContentPlugin.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { EditorPlugin, IEditor, PluginEvent } from 'roosterjs-content-model-types';\nimport { PluginEventType } from '../../utils/RichTextEditorUtils';\n\n/**\n * An update mode to indicate when the content update happens\n */\nexport enum UpdateEvent {\n Init = 'Init',\n Dispose = 'Dispose',\n ContentChanged = 'ContentChanged',\n UserInput = 'UserInput',\n Blur = 'Blur'\n}\n\nconst enum Keys {\n BACKSPACE = 8,\n DELETE = 46\n}\n\n/**\n * A plugin to handle content update\n */\nexport class UpdateContentPlugin implements EditorPlugin {\n private editor: IEditor | null = null;\n private disposer: (() => void) | null = null;\n // don't set callback in constructor to be able to update callback without plugin recreation\n onUpdate: ((event: UpdateEvent, imageSrcArray?: Array<string>) => void) | null = null;\n\n getName(): string {\n return 'UpdateContentPlugin';\n }\n\n /**\n * Initialize this plugin\n * @param editor The editor instance\n */\n initialize(editor: IEditor): void {\n this.editor = editor;\n this.disposer = this.editor.attachDomEvent({\n blur: { beforeDispatch: this.onBlur }\n });\n }\n\n dispose(): void {\n this.editor = null;\n\n if (this.disposer) {\n this.disposer();\n this.disposer = null;\n }\n }\n\n onPluginEvent(event: PluginEvent): void {\n if (this.onUpdate === null) {\n return;\n }\n let imageSrcArray: Array<string> | undefined;\n\n switch (event.eventType) {\n case PluginEventType.EditorReady:\n this.onUpdate(UpdateEvent.Init);\n break;\n\n case PluginEventType.BeforeDispose:\n this.onUpdate(UpdateEvent.Dispose);\n break;\n\n case PluginEventType.ContentChanged:\n if (\n event.source.toLowerCase() === 'cut' ||\n (event.source.toLowerCase() === 'keyboard' && (event.data === Keys.BACKSPACE || event.data === Keys.DELETE))\n ) {\n imageSrcArray = [];\n event.contentModel?.blocks.map((block) => {\n if (block.blockType === 'Paragraph') {\n const segments = block.segments;\n segments.map((segment) => {\n if (segment.segmentType === 'Image') {\n imageSrcArray?.push(segment.src);\n }\n });\n }\n });\n }\n this.onUpdate(UpdateEvent.ContentChanged, imageSrcArray);\n break;\n\n case PluginEventType.Input:\n this.onUpdate(UpdateEvent.UserInput);\n break;\n }\n }\n\n private onBlur = (): void => {\n if (this.onUpdate === null) {\n return;\n }\n this.onUpdate(UpdateEvent.Blur);\n };\n}\n"]}
@@ -11,7 +11,7 @@ import { InputBoxButton } from '../InputBoxButton';
11
11
  import { RichTextSendBoxErrors } from './RichTextSendBoxErrors';
12
12
  import { isMessageTooLong, isSendBoxButtonAriaDisabled, sanitizeText } from '../utils/SendBoxUtils';
13
13
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
14
- import { insertImagesToContentString } from '../utils/SendBoxUtils';
14
+ import { insertImagesToContentString, cancelInlineImageUpload } from '../utils/SendBoxUtils';
15
15
  import { useTheme } from '../../theming';
16
16
  import { richTextActionButtonsStyle, sendBoxRichTextEditorStyle } from '../styles/RichTextEditor.styles';
17
17
  /* @conditional-compile-remove(file-sharing-acs) */
@@ -69,13 +69,7 @@ export const RichTextSendBox = (props) => {
69
69
  const onChangeHandler = useCallback((newValue,
70
70
  /* @conditional-compile-remove(rich-text-editor-image-upload) */ imageSrcArray) => {
71
71
  /* @conditional-compile-remove(rich-text-editor-image-upload) */
72
- if (imageSrcArray && imageUploadsInProgress && (imageUploadsInProgress === null || imageUploadsInProgress === void 0 ? void 0 : imageUploadsInProgress.length) > 0) {
73
- imageUploadsInProgress === null || imageUploadsInProgress === void 0 ? void 0 : imageUploadsInProgress.map((uploadImage) => {
74
- if (uploadImage.url && imageSrcArray && !(imageSrcArray === null || imageSrcArray === void 0 ? void 0 : imageSrcArray.includes(uploadImage.url))) {
75
- onCancelInlineImageUpload === null || onCancelInlineImageUpload === void 0 ? void 0 : onCancelInlineImageUpload(uploadImage.id);
76
- }
77
- });
78
- }
72
+ cancelInlineImageUpload(imageSrcArray, imageUploadsInProgress, onCancelInlineImageUpload);
79
73
  setContent(newValue);
80
74
  }, [
81
75
  setContent,
@@ -1 +1 @@
1
- {"version":3,"file":"RichTextSendBox.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RichTextEditor/RichTextSendBox.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\nimport { RichTextInputBoxComponent } from './RichTextInputBoxComponent';\nimport { Icon, Stack } from '@fluentui/react';\nimport { useLocale } from '../../localization';\nimport { SendBoxStrings } from '../SendBox';\nimport { sendIconStyle } from '../styles/SendBox.styles';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { useV9CustomStyles } from '../styles/SendBox.styles';\nimport { InputBoxButton } from '../InputBoxButton';\nimport { RichTextSendBoxErrors, RichTextSendBoxErrorsProps } from './RichTextSendBoxErrors';\nimport { isMessageTooLong, isSendBoxButtonAriaDisabled, sanitizeText } from '../utils/SendBoxUtils';\n/* @conditional-compile-remove(rich-text-editor-image-upload) */\nimport { insertImagesToContentString } from '../utils/SendBoxUtils';\nimport { RichTextEditorComponentRef } from './RichTextEditor';\nimport { useTheme } from '../../theming';\nimport { richTextActionButtonsStyle, sendBoxRichTextEditorStyle } from '../styles/RichTextEditor.styles';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { _AttachmentUploadCards } from '../Attachment/AttachmentUploadCards';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { AttachmentMetadataInProgress, MessageOptions } from '@internal/acs-ui-common';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport {\n isAttachmentUploadCompleted,\n hasIncompleteAttachmentUploads,\n toAttachmentMetadata\n} from '../utils/SendBoxUtils';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { SendBoxErrorBarError } from '../SendBoxErrorBar';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { attachmentUploadCardsStyles } from '../styles/SendBox.styles';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { FluentV9ThemeProvider } from '../../theming/FluentV9ThemeProvider';\n\n/**\n * Strings of {@link RichTextSendBox} that can be overridden.\n *\n * @beta\n */\nexport interface RichTextSendBoxStrings extends RichTextStrings, SendBoxStrings {}\n\n/**\n * Strings of RichText that can be overridden.\n *\n * @beta\n */\nexport interface RichTextStrings {\n /**\n * Tooltip text for the bold button.\n */\n richTextBoldTooltip: string;\n /**\n * Tooltip text for the italic button.\n */\n richTextItalicTooltip: string;\n /**\n * Tooltip text for the underline button.\n */\n richTextUnderlineTooltip: string;\n /**\n * Tooltip text for the bullet list button.\n */\n richTextBulletListTooltip: string;\n /**\n * Tooltip text for the number list button.\n */\n richTextNumberListTooltip: string;\n /**\n * Tooltip text for the increase indent button.\n */\n richTextIncreaseIndentTooltip: string;\n /**\n * Tooltip text for the decrease indent button.\n */\n richTextDecreaseIndentTooltip: string;\n /**\n * Tooltip text insert table button.\n */\n richTextInsertTableTooltip: string;\n /**\n * Tooltip text for the rich text format button button.\n */\n richTextFormatButtonTooltip: string;\n /**\n * Text for the insert menu item.\n */\n richTextInsertRowOrColumnMenu: string;\n /**\n * Title for the insert table menu.\n */\n richTextInsertTableMenuTitle: string;\n /**\n * Text for the insert menu item to insert row above the current selection.\n */\n richTextInsertRowAboveMenu: string;\n /**\n * Text for the insert menu item to insert row below the current selection.\n */\n richTextInsertRowBelowMenu: string;\n /**\n * Text for the insert menu item to insert column to the left from the current selection.\n */\n richTextInsertColumnLeftMenu: string;\n /**\n * Text for the insert menu item to insert column to the right from the current selection.\n */\n richTextInsertColumnRightMenu: string;\n /**\n * Text for the delete row or column menu.\n */\n richTextDeleteRowOrColumnMenu: string;\n /**\n * Text for the delete column menu.\n */\n richTextDeleteColumnMenu: string;\n /**\n * Text for the delete row menu.\n */\n richTextDeleteRowMenu: string;\n /**\n * Text for the delete table menu.\n */\n richTextDeleteTableMenu: string;\n /**\n * Text for the rich text toolbar more button.\n */\n richTextToolbarMoreButtonAriaLabel: string;\n}\n\n/**\n * Props for {@link RichTextSendBox}.\n *\n * @beta\n */\nexport interface RichTextSendBoxProps {\n /**\n * Optional boolean to disable text box\n * @defaultValue false\n */\n disabled?: boolean;\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n /**\n * Optional callback to handle paste event.\n */\n onPaste?: (event: { content: DocumentFragment }) => void;\n /**\n * Optional strings to override in component\n */\n strings?: Partial<RichTextSendBoxStrings>;\n /**\n * Optional text for system message above the text box\n */\n systemMessage?: string;\n /* @conditional-compile-remove(file-sharing-acs) */\n /**\n * Optional array of type {@link AttachmentMetadataInProgress}\n * to render attachments being uploaded in the SendBox.\n * @beta\n */\n attachments?: AttachmentMetadataInProgress[];\n /**\n * enumerable to determine if the input box has focus on render or not.\n * When undefined nothing has focus on render\n */\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(file-sharing-acs) */\n /**\n * Optional callback to remove the attachment upload before sending by clicking on\n * cancel icon.\n */\n onCancelAttachmentUpload?: (attachmentId: string) => void;\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n /**\n * Optional callback to remove the attachment upload or delete the image before sending.\n */\n onCancelInlineImageUpload?: (imageId: string) => void;\n /**\n * Callback function used when the send button is clicked.\n */\n onSendMessage: (\n content: string,\n /* @conditional-compile-remove(file-sharing-acs) */\n options?: MessageOptions\n ) => Promise<void>;\n /**\n * Optional callback called when user is typing\n */\n onTyping?: () => Promise<void>;\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n /**\n * Optional callback to upload an inline image in the rich text editor.\n */\n onUploadInlineImage?: (imageUrl: string, imageFileName: string) => void;\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n /**\n * Optional array of type {@link AttachmentMetadataInProgress}\n * to render inline images being uploaded in the RichTextSendBox.\n */\n imageUploadsInProgress?: AttachmentMetadataInProgress[];\n}\n\n/**\n * A component to render SendBox with Rich Text Editor support.\n *\n * @beta\n */\nexport const RichTextSendBox = (props: RichTextSendBoxProps): JSX.Element => {\n const {\n disabled = false,\n systemMessage,\n autoFocus,\n onSendMessage,\n onTyping,\n /* @conditional-compile-remove(file-sharing-acs) */\n attachments,\n /* @conditional-compile-remove(file-sharing-acs) */\n onCancelAttachmentUpload,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onPaste,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onUploadInlineImage,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n imageUploadsInProgress,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onCancelInlineImageUpload\n } = props;\n\n const theme = useTheme();\n const locale = useLocale();\n\n const localeStrings = useMemo(() => {\n /* @conditional-compile-remove(rich-text-editor) */\n return locale.strings.richTextSendBox;\n return locale.strings.sendBox;\n }, [/* @conditional-compile-remove(rich-text-editor) */ locale.strings.richTextSendBox, locale.strings.sendBox]);\n\n const strings = useMemo(() => {\n return { ...localeStrings, ...props.strings };\n }, [localeStrings, props.strings]);\n\n const [contentValue, setContentValue] = useState('');\n const [contentValueOverflow, setContentValueOverflow] = useState(false);\n /* @conditional-compile-remove(file-sharing-acs) */\n const [attachmentUploadsPendingError, setAttachmentUploadsPendingError] = useState<SendBoxErrorBarError | undefined>(\n undefined\n );\n const editorComponentRef = useRef<RichTextEditorComponentRef>(null);\n\n /* @conditional-compile-remove(file-sharing-acs) */\n const customV9Styles = useV9CustomStyles();\n\n const contentTooLongMessage = useMemo(\n () => (contentValueOverflow ? strings.textTooLong : undefined),\n [contentValueOverflow, strings.textTooLong]\n );\n\n const setContent = useCallback((newValue?: string): void => {\n if (newValue === undefined) {\n return;\n }\n\n setContentValueOverflow(isMessageTooLong(newValue.length));\n setContentValue(newValue);\n }, []);\n\n const onChangeHandler = useCallback(\n (\n newValue?: string,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ imageSrcArray?: Array<string>\n ) => {\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n if (imageSrcArray && imageUploadsInProgress && imageUploadsInProgress?.length > 0) {\n imageUploadsInProgress?.map((uploadImage) => {\n if (uploadImage.url && imageSrcArray && !imageSrcArray?.includes(uploadImage.url)) {\n onCancelInlineImageUpload?.(uploadImage.id);\n }\n });\n }\n\n setContent(newValue);\n },\n [\n setContent,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ onCancelInlineImageUpload,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ imageUploadsInProgress\n ]\n );\n\n const hasContent = useMemo(() => {\n // get plain text content from the editor to check if the message is empty\n // as the content may contain tags even when the content is empty\n const plainTextContent = editorComponentRef.current?.getPlainContent();\n return sanitizeText(contentValue ?? '').length > 0 && sanitizeText(plainTextContent ?? '').length > 0;\n }, [contentValue]);\n\n const sendMessageOnClick = useCallback((): void => {\n if (disabled || contentValueOverflow) {\n return;\n }\n // Don't send message until all attachments have been uploaded successfully\n /* @conditional-compile-remove(file-sharing-acs) */\n setAttachmentUploadsPendingError(undefined);\n\n /* @conditional-compile-remove(file-sharing-acs) */\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n if (\n /* @conditional-compile-remove(file-sharing-acs) */ hasIncompleteAttachmentUploads(attachments) ||\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ hasIncompleteAttachmentUploads(\n imageUploadsInProgress\n )\n ) {\n setAttachmentUploadsPendingError({ message: strings.attachmentUploadsPendingError, timestamp: Date.now() });\n return;\n }\n\n let message = contentValue;\n // we don't want to send empty messages including spaces, newlines, tabs\n // Message can be empty if there is a valid attachment upload\n if (\n hasContent ||\n /* @conditional-compile-remove(file-sharing-acs) */ isAttachmentUploadCompleted(attachments) ||\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ isAttachmentUploadCompleted(\n imageUploadsInProgress\n )\n ) {\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n message = insertImagesToContentString(contentValue, imageUploadsInProgress);\n\n onSendMessage(\n message,\n /* @conditional-compile-remove(file-sharing-acs) */ /* @conditional-compile-remove(rich-text-editor-composite-support) */\n {\n /* @conditional-compile-remove(file-sharing-acs) */\n attachments: toAttachmentMetadata(attachments),\n /* @conditional-compile-remove(rich-text-editor-composite-support) */\n type: 'html'\n }\n );\n setContentValue('');\n editorComponentRef.current?.setEmptyContent();\n editorComponentRef.current?.focus();\n }\n }, [\n disabled,\n contentValueOverflow,\n /* @conditional-compile-remove(file-sharing-acs) */\n attachments,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n imageUploadsInProgress,\n contentValue,\n hasContent,\n /* @conditional-compile-remove(file-sharing-acs) */\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n strings.attachmentUploadsPendingError,\n onSendMessage\n ]);\n\n const hasErrorMessage = useMemo(() => {\n return (\n !!systemMessage ||\n !!contentTooLongMessage ||\n /* @conditional-compile-remove(file-sharing-acs) */\n !!attachmentUploadsPendingError ||\n /* @conditional-compile-remove(file-sharing-acs) */\n !!attachments?.filter((attachmentUpload) => attachmentUpload.error).pop()?.error ||\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n !!imageUploadsInProgress?.filter((image) => image.error).pop()?.error\n );\n }, [\n /* @conditional-compile-remove(file-sharing-acs) */\n attachments,\n contentTooLongMessage,\n /* @conditional-compile-remove(file-sharing-acs) */\n attachmentUploadsPendingError,\n systemMessage,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n imageUploadsInProgress\n ]);\n\n const onRenderSendIcon = useCallback(\n (isHover: boolean) => {\n return (\n <Icon\n iconName={isHover && hasContent ? 'SendBoxSendHovered' : 'SendBoxSend'}\n className={sendIconStyle({\n theme,\n hasText: hasContent,\n /* @conditional-compile-remove(file-sharing-acs) */\n hasAttachment: false,\n hasErrorMessage: hasErrorMessage,\n defaultTextColor: theme.palette.neutralSecondary,\n disabled: disabled\n })}\n />\n );\n },\n [disabled, hasContent, hasErrorMessage, theme]\n );\n\n const sendBoxErrorsProps: RichTextSendBoxErrorsProps = useMemo(() => {\n /* @conditional-compile-remove(file-sharing-acs) */\n const uploadErrorMessage = attachments?.filter((attachmentUpload) => attachmentUpload.error).pop()?.error?.message;\n return {\n /* @conditional-compile-remove(file-sharing-acs) */\n attachmentUploadsPendingError: attachmentUploadsPendingError,\n /* @conditional-compile-remove(file-sharing-acs) */\n attachmentProgressError: uploadErrorMessage\n ? {\n message: uploadErrorMessage,\n timestamp: Date.now()\n }\n : undefined,\n systemMessage: systemMessage,\n textTooLongMessage: contentTooLongMessage\n };\n }, [\n /* @conditional-compile-remove(file-sharing-acs) */\n attachments,\n contentTooLongMessage,\n /* @conditional-compile-remove(file-sharing-acs) */\n attachmentUploadsPendingError,\n systemMessage\n ]);\n\n /* @conditional-compile-remove(file-sharing-acs) */\n const onRenderAttachmentUploads = useCallback(() => {\n return (\n <Stack className={attachmentUploadCardsStyles}>\n <FluentV9ThemeProvider v8Theme={theme} className={customV9Styles.clearBackground}>\n <_AttachmentUploadCards\n attachments={attachments}\n onCancelAttachmentUpload={onCancelAttachmentUpload}\n strings={{\n removeAttachment: strings.removeAttachment,\n uploading: strings.uploading,\n uploadCompleted: strings.uploadCompleted,\n attachmentMoreMenu: strings.attachmentMoreMenu\n }}\n disabled={disabled}\n />\n </FluentV9ThemeProvider>\n </Stack>\n );\n }, [\n theme,\n customV9Styles.clearBackground,\n attachments,\n onCancelAttachmentUpload,\n strings.removeAttachment,\n strings.uploading,\n strings.uploadCompleted,\n strings.attachmentMoreMenu,\n disabled\n ]);\n\n const isSendBoxButtonAriaDisabledValue = useMemo(() => {\n return isSendBoxButtonAriaDisabled({\n hasContent,\n /* @conditional-compile-remove(file-sharing-acs) */ hasCompletedAttachmentUploads:\n isAttachmentUploadCompleted(attachments),\n hasError: hasErrorMessage,\n disabled\n });\n }, [/* @conditional-compile-remove(file-sharing-acs) */ attachments, disabled, hasContent, hasErrorMessage]);\n\n const sendButton = useMemo(() => {\n return (\n <InputBoxButton\n onRenderIcon={onRenderSendIcon}\n onClick={(e) => {\n sendMessageOnClick();\n e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.\n }}\n className={richTextActionButtonsStyle}\n ariaLabel={localeStrings.sendButtonAriaLabel}\n tooltipContent={localeStrings.sendButtonAriaLabel}\n ariaDisabled={isSendBoxButtonAriaDisabledValue}\n />\n );\n }, [isSendBoxButtonAriaDisabledValue, localeStrings.sendButtonAriaLabel, onRenderSendIcon, sendMessageOnClick]);\n\n /* @conditional-compile-remove(file-sharing-acs) */\n const hasAttachmentUploads = useMemo(() => {\n return isAttachmentUploadCompleted(attachments) || hasIncompleteAttachmentUploads(attachments);\n }, [attachments]);\n\n return (\n <Stack>\n <RichTextSendBoxErrors {...sendBoxErrorsProps} />\n <RichTextInputBoxComponent\n placeholderText={strings.placeholderText}\n autoFocus={autoFocus}\n onChange={onChangeHandler}\n onEnterKeyDown={sendMessageOnClick}\n onTyping={onTyping}\n editorComponentRef={editorComponentRef}\n strings={strings}\n disabled={disabled}\n actionComponents={sendButton}\n richTextEditorStyleProps={sendBoxRichTextEditorStyle}\n /* @conditional-compile-remove(file-sharing-acs) */\n onRenderAttachmentUploads={onRenderAttachmentUploads}\n /* @conditional-compile-remove(file-sharing-acs) */\n hasAttachments={hasAttachmentUploads}\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onPaste={onPaste}\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onUploadInlineImage={onUploadInlineImage}\n />\n </Stack>\n );\n};\n"]}
1
+ {"version":3,"file":"RichTextSendBox.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/RichTextEditor/RichTextSendBox.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\nimport { RichTextInputBoxComponent } from './RichTextInputBoxComponent';\nimport { Icon, Stack } from '@fluentui/react';\nimport { useLocale } from '../../localization';\nimport { SendBoxStrings } from '../SendBox';\nimport { sendIconStyle } from '../styles/SendBox.styles';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { useV9CustomStyles } from '../styles/SendBox.styles';\nimport { InputBoxButton } from '../InputBoxButton';\nimport { RichTextSendBoxErrors, RichTextSendBoxErrorsProps } from './RichTextSendBoxErrors';\nimport { isMessageTooLong, isSendBoxButtonAriaDisabled, sanitizeText } from '../utils/SendBoxUtils';\n/* @conditional-compile-remove(rich-text-editor-image-upload) */\nimport { insertImagesToContentString, cancelInlineImageUpload } from '../utils/SendBoxUtils';\nimport { RichTextEditorComponentRef } from './RichTextEditor';\nimport { useTheme } from '../../theming';\nimport { richTextActionButtonsStyle, sendBoxRichTextEditorStyle } from '../styles/RichTextEditor.styles';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { _AttachmentUploadCards } from '../Attachment/AttachmentUploadCards';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { AttachmentMetadataInProgress, MessageOptions } from '@internal/acs-ui-common';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport {\n isAttachmentUploadCompleted,\n hasIncompleteAttachmentUploads,\n toAttachmentMetadata\n} from '../utils/SendBoxUtils';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { SendBoxErrorBarError } from '../SendBoxErrorBar';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { attachmentUploadCardsStyles } from '../styles/SendBox.styles';\n/* @conditional-compile-remove(file-sharing-acs) */\nimport { FluentV9ThemeProvider } from '../../theming/FluentV9ThemeProvider';\n\n/**\n * Strings of {@link RichTextSendBox} that can be overridden.\n *\n * @beta\n */\nexport interface RichTextSendBoxStrings extends RichTextStrings, SendBoxStrings {}\n\n/**\n * Strings of RichText that can be overridden.\n *\n * @beta\n */\nexport interface RichTextStrings {\n /**\n * Tooltip text for the bold button.\n */\n richTextBoldTooltip: string;\n /**\n * Tooltip text for the italic button.\n */\n richTextItalicTooltip: string;\n /**\n * Tooltip text for the underline button.\n */\n richTextUnderlineTooltip: string;\n /**\n * Tooltip text for the bullet list button.\n */\n richTextBulletListTooltip: string;\n /**\n * Tooltip text for the number list button.\n */\n richTextNumberListTooltip: string;\n /**\n * Tooltip text for the increase indent button.\n */\n richTextIncreaseIndentTooltip: string;\n /**\n * Tooltip text for the decrease indent button.\n */\n richTextDecreaseIndentTooltip: string;\n /**\n * Tooltip text insert table button.\n */\n richTextInsertTableTooltip: string;\n /**\n * Tooltip text for the rich text format button button.\n */\n richTextFormatButtonTooltip: string;\n /**\n * Text for the insert menu item.\n */\n richTextInsertRowOrColumnMenu: string;\n /**\n * Title for the insert table menu.\n */\n richTextInsertTableMenuTitle: string;\n /**\n * Text for the insert menu item to insert row above the current selection.\n */\n richTextInsertRowAboveMenu: string;\n /**\n * Text for the insert menu item to insert row below the current selection.\n */\n richTextInsertRowBelowMenu: string;\n /**\n * Text for the insert menu item to insert column to the left from the current selection.\n */\n richTextInsertColumnLeftMenu: string;\n /**\n * Text for the insert menu item to insert column to the right from the current selection.\n */\n richTextInsertColumnRightMenu: string;\n /**\n * Text for the delete row or column menu.\n */\n richTextDeleteRowOrColumnMenu: string;\n /**\n * Text for the delete column menu.\n */\n richTextDeleteColumnMenu: string;\n /**\n * Text for the delete row menu.\n */\n richTextDeleteRowMenu: string;\n /**\n * Text for the delete table menu.\n */\n richTextDeleteTableMenu: string;\n /**\n * Text for the rich text toolbar more button.\n */\n richTextToolbarMoreButtonAriaLabel: string;\n}\n\n/**\n * Props for {@link RichTextSendBox}.\n *\n * @beta\n */\nexport interface RichTextSendBoxProps {\n /**\n * Optional boolean to disable text box\n * @defaultValue false\n */\n disabled?: boolean;\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n /**\n * Optional callback to handle paste event.\n */\n onPaste?: (event: { content: DocumentFragment }) => void;\n /**\n * Optional strings to override in component\n */\n strings?: Partial<RichTextSendBoxStrings>;\n /**\n * Optional text for system message above the text box\n */\n systemMessage?: string;\n /* @conditional-compile-remove(file-sharing-acs) */\n /**\n * Optional array of type {@link AttachmentMetadataInProgress}\n * to render attachments being uploaded in the SendBox.\n * @beta\n */\n attachments?: AttachmentMetadataInProgress[];\n /**\n * enumerable to determine if the input box has focus on render or not.\n * When undefined nothing has focus on render\n */\n autoFocus?: 'sendBoxTextField';\n /* @conditional-compile-remove(file-sharing-acs) */\n /**\n * Optional callback to remove the attachment upload before sending by clicking on\n * cancel icon.\n */\n onCancelAttachmentUpload?: (attachmentId: string) => void;\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n /**\n * Optional callback to remove the attachment upload or delete the image before sending.\n */\n onCancelInlineImageUpload?: (imageId: string) => void;\n /**\n * Callback function used when the send button is clicked.\n */\n onSendMessage: (\n content: string,\n /* @conditional-compile-remove(file-sharing-acs) */\n options?: MessageOptions\n ) => Promise<void>;\n /**\n * Optional callback called when user is typing\n */\n onTyping?: () => Promise<void>;\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n /**\n * Optional callback to upload an inline image in the rich text editor.\n */\n onUploadInlineImage?: (imageUrl: string, imageFileName: string) => void;\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n /**\n * Optional array of type {@link AttachmentMetadataInProgress}\n * to render inline images being uploaded in the RichTextSendBox.\n */\n imageUploadsInProgress?: AttachmentMetadataInProgress[];\n}\n\n/**\n * A component to render SendBox with Rich Text Editor support.\n *\n * @beta\n */\nexport const RichTextSendBox = (props: RichTextSendBoxProps): JSX.Element => {\n const {\n disabled = false,\n systemMessage,\n autoFocus,\n onSendMessage,\n onTyping,\n /* @conditional-compile-remove(file-sharing-acs) */\n attachments,\n /* @conditional-compile-remove(file-sharing-acs) */\n onCancelAttachmentUpload,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onPaste,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onUploadInlineImage,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n imageUploadsInProgress,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onCancelInlineImageUpload\n } = props;\n\n const theme = useTheme();\n const locale = useLocale();\n\n const localeStrings = useMemo(() => {\n /* @conditional-compile-remove(rich-text-editor) */\n return locale.strings.richTextSendBox;\n return locale.strings.sendBox;\n }, [/* @conditional-compile-remove(rich-text-editor) */ locale.strings.richTextSendBox, locale.strings.sendBox]);\n\n const strings = useMemo(() => {\n return { ...localeStrings, ...props.strings };\n }, [localeStrings, props.strings]);\n\n const [contentValue, setContentValue] = useState('');\n const [contentValueOverflow, setContentValueOverflow] = useState(false);\n /* @conditional-compile-remove(file-sharing-acs) */\n const [attachmentUploadsPendingError, setAttachmentUploadsPendingError] = useState<SendBoxErrorBarError | undefined>(\n undefined\n );\n const editorComponentRef = useRef<RichTextEditorComponentRef>(null);\n\n /* @conditional-compile-remove(file-sharing-acs) */\n const customV9Styles = useV9CustomStyles();\n\n const contentTooLongMessage = useMemo(\n () => (contentValueOverflow ? strings.textTooLong : undefined),\n [contentValueOverflow, strings.textTooLong]\n );\n\n const setContent = useCallback((newValue?: string): void => {\n if (newValue === undefined) {\n return;\n }\n\n setContentValueOverflow(isMessageTooLong(newValue.length));\n setContentValue(newValue);\n }, []);\n\n const onChangeHandler = useCallback(\n (\n newValue?: string,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ imageSrcArray?: Array<string>\n ) => {\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n cancelInlineImageUpload(imageSrcArray, imageUploadsInProgress, onCancelInlineImageUpload);\n setContent(newValue);\n },\n [\n setContent,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ onCancelInlineImageUpload,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ imageUploadsInProgress\n ]\n );\n\n const hasContent = useMemo(() => {\n // get plain text content from the editor to check if the message is empty\n // as the content may contain tags even when the content is empty\n const plainTextContent = editorComponentRef.current?.getPlainContent();\n return sanitizeText(contentValue ?? '').length > 0 && sanitizeText(plainTextContent ?? '').length > 0;\n }, [contentValue]);\n\n const sendMessageOnClick = useCallback((): void => {\n if (disabled || contentValueOverflow) {\n return;\n }\n // Don't send message until all attachments have been uploaded successfully\n /* @conditional-compile-remove(file-sharing-acs) */\n setAttachmentUploadsPendingError(undefined);\n\n /* @conditional-compile-remove(file-sharing-acs) */\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n if (\n /* @conditional-compile-remove(file-sharing-acs) */ hasIncompleteAttachmentUploads(attachments) ||\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ hasIncompleteAttachmentUploads(\n imageUploadsInProgress\n )\n ) {\n setAttachmentUploadsPendingError({ message: strings.attachmentUploadsPendingError, timestamp: Date.now() });\n return;\n }\n\n let message = contentValue;\n // we don't want to send empty messages including spaces, newlines, tabs\n // Message can be empty if there is a valid attachment upload\n if (\n hasContent ||\n /* @conditional-compile-remove(file-sharing-acs) */ isAttachmentUploadCompleted(attachments) ||\n /* @conditional-compile-remove(rich-text-editor-image-upload) */ isAttachmentUploadCompleted(\n imageUploadsInProgress\n )\n ) {\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n message = insertImagesToContentString(contentValue, imageUploadsInProgress);\n\n onSendMessage(\n message,\n /* @conditional-compile-remove(file-sharing-acs) */ /* @conditional-compile-remove(rich-text-editor-composite-support) */\n {\n /* @conditional-compile-remove(file-sharing-acs) */\n attachments: toAttachmentMetadata(attachments),\n /* @conditional-compile-remove(rich-text-editor-composite-support) */\n type: 'html'\n }\n );\n setContentValue('');\n editorComponentRef.current?.setEmptyContent();\n editorComponentRef.current?.focus();\n }\n }, [\n disabled,\n contentValueOverflow,\n /* @conditional-compile-remove(file-sharing-acs) */\n attachments,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n imageUploadsInProgress,\n contentValue,\n hasContent,\n /* @conditional-compile-remove(file-sharing-acs) */\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n strings.attachmentUploadsPendingError,\n onSendMessage\n ]);\n\n const hasErrorMessage = useMemo(() => {\n return (\n !!systemMessage ||\n !!contentTooLongMessage ||\n /* @conditional-compile-remove(file-sharing-acs) */\n !!attachmentUploadsPendingError ||\n /* @conditional-compile-remove(file-sharing-acs) */\n !!attachments?.filter((attachmentUpload) => attachmentUpload.error).pop()?.error ||\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n !!imageUploadsInProgress?.filter((image) => image.error).pop()?.error\n );\n }, [\n /* @conditional-compile-remove(file-sharing-acs) */\n attachments,\n contentTooLongMessage,\n /* @conditional-compile-remove(file-sharing-acs) */\n attachmentUploadsPendingError,\n systemMessage,\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n imageUploadsInProgress\n ]);\n\n const onRenderSendIcon = useCallback(\n (isHover: boolean) => {\n return (\n <Icon\n iconName={isHover && hasContent ? 'SendBoxSendHovered' : 'SendBoxSend'}\n className={sendIconStyle({\n theme,\n hasText: hasContent,\n /* @conditional-compile-remove(file-sharing-acs) */\n hasAttachment: false,\n hasErrorMessage: hasErrorMessage,\n defaultTextColor: theme.palette.neutralSecondary,\n disabled: disabled\n })}\n />\n );\n },\n [disabled, hasContent, hasErrorMessage, theme]\n );\n\n const sendBoxErrorsProps: RichTextSendBoxErrorsProps = useMemo(() => {\n /* @conditional-compile-remove(file-sharing-acs) */\n const uploadErrorMessage = attachments?.filter((attachmentUpload) => attachmentUpload.error).pop()?.error?.message;\n return {\n /* @conditional-compile-remove(file-sharing-acs) */\n attachmentUploadsPendingError: attachmentUploadsPendingError,\n /* @conditional-compile-remove(file-sharing-acs) */\n attachmentProgressError: uploadErrorMessage\n ? {\n message: uploadErrorMessage,\n timestamp: Date.now()\n }\n : undefined,\n systemMessage: systemMessage,\n textTooLongMessage: contentTooLongMessage\n };\n }, [\n /* @conditional-compile-remove(file-sharing-acs) */\n attachments,\n contentTooLongMessage,\n /* @conditional-compile-remove(file-sharing-acs) */\n attachmentUploadsPendingError,\n systemMessage\n ]);\n\n /* @conditional-compile-remove(file-sharing-acs) */\n const onRenderAttachmentUploads = useCallback(() => {\n return (\n <Stack className={attachmentUploadCardsStyles}>\n <FluentV9ThemeProvider v8Theme={theme} className={customV9Styles.clearBackground}>\n <_AttachmentUploadCards\n attachments={attachments}\n onCancelAttachmentUpload={onCancelAttachmentUpload}\n strings={{\n removeAttachment: strings.removeAttachment,\n uploading: strings.uploading,\n uploadCompleted: strings.uploadCompleted,\n attachmentMoreMenu: strings.attachmentMoreMenu\n }}\n disabled={disabled}\n />\n </FluentV9ThemeProvider>\n </Stack>\n );\n }, [\n theme,\n customV9Styles.clearBackground,\n attachments,\n onCancelAttachmentUpload,\n strings.removeAttachment,\n strings.uploading,\n strings.uploadCompleted,\n strings.attachmentMoreMenu,\n disabled\n ]);\n\n const isSendBoxButtonAriaDisabledValue = useMemo(() => {\n return isSendBoxButtonAriaDisabled({\n hasContent,\n /* @conditional-compile-remove(file-sharing-acs) */ hasCompletedAttachmentUploads:\n isAttachmentUploadCompleted(attachments),\n hasError: hasErrorMessage,\n disabled\n });\n }, [/* @conditional-compile-remove(file-sharing-acs) */ attachments, disabled, hasContent, hasErrorMessage]);\n\n const sendButton = useMemo(() => {\n return (\n <InputBoxButton\n onRenderIcon={onRenderSendIcon}\n onClick={(e) => {\n sendMessageOnClick();\n e.stopPropagation(); // Prevents the click from bubbling up and triggering a focus event on the chat.\n }}\n className={richTextActionButtonsStyle}\n ariaLabel={localeStrings.sendButtonAriaLabel}\n tooltipContent={localeStrings.sendButtonAriaLabel}\n ariaDisabled={isSendBoxButtonAriaDisabledValue}\n />\n );\n }, [isSendBoxButtonAriaDisabledValue, localeStrings.sendButtonAriaLabel, onRenderSendIcon, sendMessageOnClick]);\n\n /* @conditional-compile-remove(file-sharing-acs) */\n const hasAttachmentUploads = useMemo(() => {\n return isAttachmentUploadCompleted(attachments) || hasIncompleteAttachmentUploads(attachments);\n }, [attachments]);\n\n return (\n <Stack>\n <RichTextSendBoxErrors {...sendBoxErrorsProps} />\n <RichTextInputBoxComponent\n placeholderText={strings.placeholderText}\n autoFocus={autoFocus}\n onChange={onChangeHandler}\n onEnterKeyDown={sendMessageOnClick}\n onTyping={onTyping}\n editorComponentRef={editorComponentRef}\n strings={strings}\n disabled={disabled}\n actionComponents={sendButton}\n richTextEditorStyleProps={sendBoxRichTextEditorStyle}\n /* @conditional-compile-remove(file-sharing-acs) */\n onRenderAttachmentUploads={onRenderAttachmentUploads}\n /* @conditional-compile-remove(file-sharing-acs) */\n hasAttachments={hasAttachmentUploads}\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onPaste={onPaste}\n /* @conditional-compile-remove(rich-text-editor-image-upload) */\n onUploadInlineImage={onUploadInlineImage}\n />\n </Stack>\n );\n};\n"]}
@@ -9,7 +9,7 @@ export declare const _ATTACHMENT_CARD_MARGIN_IN_PX = 2;
9
9
  /**
10
10
  * @private
11
11
  */
12
- export declare const useAttachmentCardStyles: () => Record<"content" | "root" | "title" | "dynamicWidth" | "staticWidth" | "fileIcon" | "focusState" | "fileNameLabel", string>;
12
+ export declare const useAttachmentCardStyles: () => Record<"content" | "title" | "root" | "dynamicWidth" | "staticWidth" | "fileIcon" | "focusState" | "fileNameLabel", string>;
13
13
  /**
14
14
  * @private
15
15
  */
@@ -24,7 +24,7 @@ export declare const useChatMessageRenderStyles: () => Record<"rootCommon" | "ro
24
24
  /**
25
25
  * @private
26
26
  */
27
- export declare const useChatMyMessageStyles: () => Record<"root" | "body" | "menu" | "menuHidden" | "multipleAttachments" | "bodyAttached" | "menuAttached" | "menuVisible", string>;
27
+ export declare const useChatMyMessageStyles: () => Record<"body" | "menu" | "root" | "menuHidden" | "bodyWithPlaceholderImage" | "bodyAttached" | "menuAttached" | "menuVisible" | "multipleAttachmentsInViewing" | "multipleAttachmentsInEditing", string>;
28
28
  /**
29
29
  * @private
30
30
  */
@@ -36,11 +36,11 @@ export declare const chatMessageDateStyle: CSSProperties;
36
36
  /**
37
37
  * @private
38
38
  */
39
- export declare const useChatMessageStyles: () => Record<"root" | "body" | "multipleAttachments" | "bodyWithoutAvatar" | "bodyWithAvatar" | "avatarNoOverlap" | "avatarOverlap" | "bodyWithPlaceholderImage", string>;
39
+ export declare const useChatMessageStyles: () => Record<"body" | "root" | "multipleAttachments" | "bodyWithoutAvatar" | "bodyWithAvatar" | "avatarNoOverlap" | "avatarOverlap", string>;
40
40
  /**
41
41
  * @private
42
42
  */
43
- export declare const useChatMessageCommonStyles: () => Record<"failed" | "blocked" | "body", string>;
43
+ export declare const useChatMessageCommonStyles: () => Record<"failed" | "body" | "blocked" | "bodyWithPlaceholderImage", string>;
44
44
  /**
45
45
  * @private
46
46
  */