@hh.ru/magritte-ui-chat-bubble 1.1.0

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 (48) hide show
  1. package/ChatBubble.d.ts +13 -0
  2. package/ChatBubble.js +54 -0
  3. package/ChatBubble.js.map +1 -0
  4. package/ErrorAction.d.ts +11 -0
  5. package/ErrorAction.js +21 -0
  6. package/ErrorAction.js.map +1 -0
  7. package/Label.d.ts +9 -0
  8. package/Label.js +18 -0
  9. package/Label.js.map +1 -0
  10. package/Message.d.ts +9 -0
  11. package/Message.js +22 -0
  12. package/Message.js.map +1 -0
  13. package/Status.d.ts +19 -0
  14. package/Status.js +34 -0
  15. package/Status.js.map +1 -0
  16. package/chat-bubble-B2HOuNTb.js +5 -0
  17. package/chat-bubble-B2HOuNTb.js.map +1 -0
  18. package/chat-bubble-Djyvds6I.js +5 -0
  19. package/chat-bubble-Djyvds6I.js.map +1 -0
  20. package/index.css +134 -0
  21. package/index.d.ts +6 -0
  22. package/index.js +26 -0
  23. package/index.js.map +1 -0
  24. package/index.mock.d.ts +11 -0
  25. package/index.mock.js +16 -0
  26. package/index.mock.js.map +1 -0
  27. package/internal/Meta.d.ts +13 -0
  28. package/internal/Meta.js +20 -0
  29. package/internal/Meta.js.map +1 -0
  30. package/internal/Tail.d.ts +3 -0
  31. package/internal/Tail.js +16 -0
  32. package/internal/Tail.js.map +1 -0
  33. package/internal/colors.d.ts +19 -0
  34. package/internal/colors.js +31 -0
  35. package/internal/colors.js.map +1 -0
  36. package/internal/errorMenu.d.ts +2 -0
  37. package/internal/errorMenu.js +10 -0
  38. package/internal/errorMenu.js.map +1 -0
  39. package/internal/mode.d.ts +4 -0
  40. package/internal/mode.js +10 -0
  41. package/internal/mode.js.map +1 -0
  42. package/internal/utils.d.ts +11 -0
  43. package/internal/utils.js +18 -0
  44. package/internal/utils.js.map +1 -0
  45. package/package.json +41 -0
  46. package/types.d.ts +50 -0
  47. package/types.js +3 -0
  48. package/types.js.map +1 -0
@@ -0,0 +1,13 @@
1
+ import { ChatBubbleErrorAction } from '@hh.ru/magritte-ui-chat-bubble/ErrorAction';
2
+ import { ChatBubbleLabel } from '@hh.ru/magritte-ui-chat-bubble/Label';
3
+ import { ChatBubbleMessage } from '@hh.ru/magritte-ui-chat-bubble/Message';
4
+ import { ChatBubbleStatus } from '@hh.ru/magritte-ui-chat-bubble/Status';
5
+ import type { ChatBubbleProps } from '@hh.ru/magritte-ui-chat-bubble/types';
6
+ interface ChatBubbleComponents {
7
+ ErrorAction: typeof ChatBubbleErrorAction;
8
+ Label: typeof ChatBubbleLabel;
9
+ Message: typeof ChatBubbleMessage;
10
+ Status: typeof ChatBubbleStatus;
11
+ }
12
+ export declare const ChatBubble: React.ForwardRefExoticComponent<ChatBubbleProps & React.RefAttributes<HTMLDivElement>> & ChatBubbleComponents;
13
+ export {};
package/ChatBubble.js ADDED
@@ -0,0 +1,54 @@
1
+ import './index.css';
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { forwardRef, useState, useCallback, useRef, useMemo, cloneElement } from 'react';
4
+ import classnames from 'classnames';
5
+ import { ButtonDefaultPropsContext } from '@hh.ru/magritte-ui-button';
6
+ import { ChatBubbleErrorAction } from './ErrorAction.js';
7
+ import { ChatBubbleLabel } from './Label.js';
8
+ import { ChatBubbleMessage } from './Message.js';
9
+ import { ChatBubbleStatus } from './Status.js';
10
+ import { Meta } from './internal/Meta.js';
11
+ import { Tail } from './internal/Tail.js';
12
+ import { getColors } from './internal/colors.js';
13
+ import { ChatBubbleErrorMenuProvider } from './internal/errorMenu.js';
14
+ import { ChatBubbleModeProvider } from './internal/mode.js';
15
+ import { flattenFragments, isMetaHost } from './internal/utils.js';
16
+ import { IconDefaultPropsContext } from '@hh.ru/magritte-ui-icon';
17
+ import { ExclamationCircleFilledSize24 } from '@hh.ru/magritte-ui-icon/icon';
18
+ import { Menu } from '@hh.ru/magritte-ui-menu';
19
+ import { Text } from '@hh.ru/magritte-ui-typography';
20
+ import { s as styles } from './chat-bubble-Djyvds6I.js';
21
+ import '@hh.ru/magritte-common-use-multiple-refs';
22
+ import '@hh.ru/magritte-common-use-translation';
23
+ import '@hh.ru/magritte-ui-tooltip';
24
+ import './chat-bubble-B2HOuNTb.js';
25
+
26
+ const ChatBubble = forwardRef(({ actions, buttons, children, header, errorActions, mode = 'incoming', showTail = false, status, time, error = false, errorText, 'data-qa': dataQa = 'chat-bubble', className, }, ref) => {
27
+ const [menuVisible, setMenuVisible] = useState(false);
28
+ const closeErrorMenu = useCallback(() => setMenuVisible(false), []);
29
+ const activatorMenuRef = useRef(null);
30
+ const colors = getColors(mode);
31
+ const actionsIconProps = useMemo(() => ({ padding: 8, initialColor: colors.actionsIcon }), [colors]);
32
+ const buttonsProps = useMemo(() => ({ size: 'small', mode: 'secondary', style: colors.button, stretched: true }), [colors]);
33
+ /**
34
+ * Время отдаём последнему элементу контента
35
+ * Позиция времени меняется, в зависимости от компонента
36
+ * Если последний ребенок не может отрисовать, вставим meta в самый конец
37
+ */
38
+ const meta = jsx(Meta, { mode: mode, status: status, time: time });
39
+ const items = flattenFragments(children);
40
+ const lastIndex = items.length - 1;
41
+ const metaHosted = isMetaHost(items[lastIndex]);
42
+ const content = items.map((child, index) => index === lastIndex && isMetaHost(child) ? cloneElement(child, { meta }) : child);
43
+ return (jsx(ChatBubbleModeProvider, { value: mode, children: jsxs("div", { className: classnames(className, styles.chatBubble, styles[mode], {
44
+ [styles.withTail]: showTail,
45
+ }), "data-qa": dataQa, ref: ref, children: [jsxs("div", { className: styles.row, children: [jsxs("div", { className: styles.bubble, children: [header && (jsx("div", { className: styles.header, "data-qa": "chat-bubble-header", children: header })), jsxs("div", { "data-qa": "chat-bubble-content", children: [content, !metaHosted && meta] }), showTail && jsx(Tail, {})] }), mode === 'outgoing' && error && (jsxs("div", { children: [jsx(ExclamationCircleFilledSize24, { ref: activatorMenuRef, initialColor: "negative", onClick: errorActions ? () => setMenuVisible((visible) => !visible) : undefined, "data-qa": "chat-bubble-error-button", "aria-haspopup": errorActions ? 'menu' : undefined, "aria-expanded": errorActions ? menuVisible : undefined }), errorActions && (jsx(Menu, { activatorRef: activatorMenuRef, onClose: closeErrorMenu, placement: "bottom-right", visible: menuVisible, children: jsx(ChatBubbleErrorMenuProvider, { value: closeErrorMenu, children: errorActions }) }))] }))] }), mode === 'outgoing' && error && errorText && (jsx("div", { className: styles.errorText, "data-qa": "chat-bubble-error-text", children: jsx(Text, { typography: "label-4-regular", style: "negative", maxLines: 2, children: errorText }) })), buttons && (mode === 'bot' || mode === 'incoming') && (jsx(ButtonDefaultPropsContext, { props: buttonsProps, children: jsx("div", { className: styles.buttons, "data-qa": "chat-bubble-buttons", children: buttons }) })), actions && (jsx(IconDefaultPropsContext, { props: actionsIconProps, children: jsx("div", { className: styles.actions, "data-qa": "chat-bubble-actions", children: actions }) }))] }) }));
46
+ });
47
+ ChatBubble.displayName = 'ChatBubble';
48
+ ChatBubble.ErrorAction = ChatBubbleErrorAction;
49
+ ChatBubble.Label = ChatBubbleLabel;
50
+ ChatBubble.Message = ChatBubbleMessage;
51
+ ChatBubble.Status = ChatBubbleStatus;
52
+
53
+ export { ChatBubble };
54
+ //# sourceMappingURL=ChatBubble.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatBubble.js","sources":["src/ChatBubble.tsx"],"sourcesContent":["import { cloneElement, forwardRef, useCallback, useState, useMemo, useRef } from 'react';\nimport classnames from 'classnames';\n\nimport { ButtonDefaultPropsContext, type ButtonProps } from '@hh.ru/magritte-ui-button';\nimport { ChatBubbleErrorAction } from '@hh.ru/magritte-ui-chat-bubble/ErrorAction';\nimport { ChatBubbleLabel } from '@hh.ru/magritte-ui-chat-bubble/Label';\nimport { ChatBubbleMessage } from '@hh.ru/magritte-ui-chat-bubble/Message';\nimport { ChatBubbleStatus } from '@hh.ru/magritte-ui-chat-bubble/Status';\nimport { Meta } from '@hh.ru/magritte-ui-chat-bubble/internal/Meta';\nimport { Tail } from '@hh.ru/magritte-ui-chat-bubble/internal/Tail';\nimport { getColors } from '@hh.ru/magritte-ui-chat-bubble/internal/colors';\nimport { ChatBubbleErrorMenuProvider } from '@hh.ru/magritte-ui-chat-bubble/internal/errorMenu';\nimport { ChatBubbleModeProvider } from '@hh.ru/magritte-ui-chat-bubble/internal/mode';\nimport { isMetaHost, flattenFragments } from '@hh.ru/magritte-ui-chat-bubble/internal/utils';\nimport type { ChatBubbleProps } from '@hh.ru/magritte-ui-chat-bubble/types';\nimport { IconDefaultPropsContext, type IconProps } from '@hh.ru/magritte-ui-icon';\nimport { ExclamationCircleFilledSize24 } from '@hh.ru/magritte-ui-icon/icon';\nimport { Menu } from '@hh.ru/magritte-ui-menu';\nimport { Text } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './chat-bubble.less';\n\ninterface ChatBubbleComponents {\n ErrorAction: typeof ChatBubbleErrorAction;\n Label: typeof ChatBubbleLabel;\n Message: typeof ChatBubbleMessage;\n Status: typeof ChatBubbleStatus;\n}\n\nexport const ChatBubble = forwardRef<HTMLDivElement, ChatBubbleProps>(\n (\n {\n actions,\n buttons,\n children,\n header,\n errorActions,\n mode = 'incoming',\n showTail = false,\n status,\n time,\n error = false,\n errorText,\n 'data-qa': dataQa = 'chat-bubble',\n className,\n },\n ref\n ) => {\n const [menuVisible, setMenuVisible] = useState(false);\n const closeErrorMenu = useCallback(() => setMenuVisible(false), []);\n const activatorMenuRef = useRef<SVGElement>(null);\n const colors = getColors(mode);\n const actionsIconProps: Partial<IconProps> = useMemo(\n () => ({ padding: 8, initialColor: colors.actionsIcon }),\n [colors]\n );\n const buttonsProps: Partial<ButtonProps> = useMemo(\n () => ({ size: 'small', mode: 'secondary', style: colors.button, stretched: true }),\n [colors]\n );\n /**\n * Время отдаём последнему элементу контента\n * Позиция времени меняется, в зависимости от компонента\n * Если последний ребенок не может отрисовать, вставим meta в самый конец\n */\n const meta = <Meta mode={mode} status={status} time={time} />;\n const items = flattenFragments(children);\n const lastIndex = items.length - 1;\n const metaHosted = isMetaHost(items[lastIndex]);\n const content = items.map((child, index) =>\n index === lastIndex && isMetaHost(child) ? cloneElement(child, { meta }) : child\n );\n return (\n <ChatBubbleModeProvider value={mode}>\n <div\n className={classnames(className, styles.chatBubble, styles[mode], {\n [styles.withTail]: showTail,\n })}\n data-qa={dataQa}\n ref={ref}\n >\n <div className={styles.row}>\n <div className={styles.bubble}>\n {header && (\n <div className={styles.header} data-qa=\"chat-bubble-header\">\n {header}\n </div>\n )}\n <div data-qa=\"chat-bubble-content\">\n {content}\n {!metaHosted && meta}\n </div>\n {showTail && <Tail />}\n </div>\n {mode === 'outgoing' && error && (\n <div>\n <ExclamationCircleFilledSize24\n ref={activatorMenuRef}\n initialColor=\"negative\"\n onClick={errorActions ? () => setMenuVisible((visible) => !visible) : undefined}\n data-qa=\"chat-bubble-error-button\"\n aria-haspopup={errorActions ? 'menu' : undefined}\n aria-expanded={errorActions ? menuVisible : undefined}\n />\n {errorActions && (\n <Menu\n activatorRef={activatorMenuRef}\n onClose={closeErrorMenu}\n placement=\"bottom-right\"\n visible={menuVisible}\n >\n <ChatBubbleErrorMenuProvider value={closeErrorMenu}>\n {errorActions}\n </ChatBubbleErrorMenuProvider>\n </Menu>\n )}\n </div>\n )}\n </div>\n {mode === 'outgoing' && error && errorText && (\n <div className={styles.errorText} data-qa=\"chat-bubble-error-text\">\n <Text typography=\"label-4-regular\" style=\"negative\" maxLines={2}>\n {errorText}\n </Text>\n </div>\n )}\n {buttons && (mode === 'bot' || mode === 'incoming') && (\n <ButtonDefaultPropsContext props={buttonsProps}>\n <div className={styles.buttons} data-qa=\"chat-bubble-buttons\">\n {buttons}\n </div>\n </ButtonDefaultPropsContext>\n )}\n {actions && (\n <IconDefaultPropsContext props={actionsIconProps}>\n <div className={styles.actions} data-qa=\"chat-bubble-actions\">\n {actions}\n </div>\n </IconDefaultPropsContext>\n )}\n </div>\n </ChatBubbleModeProvider>\n );\n }\n) as React.ForwardRefExoticComponent<ChatBubbleProps & React.RefAttributes<HTMLDivElement>> & ChatBubbleComponents;\n\nChatBubble.displayName = 'ChatBubble';\n\nChatBubble.ErrorAction = ChatBubbleErrorAction;\nChatBubble.Label = ChatBubbleLabel;\nChatBubble.Message = ChatBubbleMessage;\nChatBubble.Status = ChatBubbleStatus;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { type MenuItemProps } from '@hh.ru/magritte-ui-menu';
2
+ export interface ChatBubbleErrorActionProps extends Pick<MenuItemProps, 'children' | 'disabled' | 'icon' | 'style' | 'subtitle' | 'onClick'> {
3
+ /** Значение data-qa
4
+ * @default chat-bubble-error-action
5
+ */
6
+ 'data-qa'?: string;
7
+ }
8
+ /**
9
+ * Пункт меню, которое открывается по нажатию на иконку ошибки отправки.
10
+ */
11
+ export declare const ChatBubbleErrorAction: import("react").ForwardRefExoticComponent<ChatBubbleErrorActionProps & import("react").RefAttributes<HTMLDivElement>>;
package/ErrorAction.js ADDED
@@ -0,0 +1,21 @@
1
+ import './index.css';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { forwardRef } from 'react';
4
+ import { useChatBubbleErrorMenuClose } from './internal/errorMenu.js';
5
+ import { Menu } from '@hh.ru/magritte-ui-menu';
6
+
7
+ /**
8
+ * Пункт меню, которое открывается по нажатию на иконку ошибки отправки.
9
+ */
10
+ const ChatBubbleErrorAction = forwardRef(({ 'data-qa': dataQa = 'chat-bubble-error-action', onClick, ...props }, ref) => {
11
+ const close = useChatBubbleErrorMenuClose();
12
+ const handleClick = (event) => {
13
+ onClick?.(event);
14
+ close();
15
+ };
16
+ return jsx(Menu.Item, { ...props, "data-qa": dataQa, onClick: handleClick, ref: ref });
17
+ });
18
+ ChatBubbleErrorAction.displayName = 'ChatBubble.ErrorAction';
19
+
20
+ export { ChatBubbleErrorAction };
21
+ //# sourceMappingURL=ErrorAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorAction.js","sources":["src/ErrorAction.tsx"],"sourcesContent":["import { forwardRef, type MouseEvent } from 'react';\n\nimport { useChatBubbleErrorMenuClose } from '@hh.ru/magritte-ui-chat-bubble/internal/errorMenu';\nimport { Menu, type MenuItemProps } from '@hh.ru/magritte-ui-menu';\n\nexport interface ChatBubbleErrorActionProps\n extends Pick<MenuItemProps, 'children' | 'disabled' | 'icon' | 'style' | 'subtitle' | 'onClick'> {\n /** Значение data-qa\n * @default chat-bubble-error-action\n */\n 'data-qa'?: string;\n}\n\n/**\n * Пункт меню, которое открывается по нажатию на иконку ошибки отправки.\n */\nexport const ChatBubbleErrorAction = forwardRef<HTMLDivElement, ChatBubbleErrorActionProps>(\n ({ 'data-qa': dataQa = 'chat-bubble-error-action', onClick, ...props }, ref) => {\n const close = useChatBubbleErrorMenuClose();\n\n const handleClick = (event: MouseEvent<HTMLDivElement>) => {\n onClick?.(event);\n close();\n };\n\n return <Menu.Item {...props} data-qa={dataQa} onClick={handleClick} ref={ref} />;\n }\n);\n\nChatBubbleErrorAction.displayName = 'ChatBubble.ErrorAction';\n"],"names":["_jsx"],"mappings":";;;;;AAaA;;AAEG;MACU,qBAAqB,GAAG,UAAU,CAC3C,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,0BAA0B,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,KAAI;AAC3E,IAAA,MAAM,KAAK,GAAG,2BAA2B,EAAE,CAAC;AAE5C,IAAA,MAAM,WAAW,GAAG,CAAC,KAAiC,KAAI;AACtD,QAAA,OAAO,GAAG,KAAK,CAAC,CAAC;AACjB,QAAA,KAAK,EAAE,CAAC;AACZ,KAAC,CAAC;AAEF,IAAA,OAAOA,IAAC,IAAI,CAAC,IAAI,EAAA,EAAA,GAAK,KAAK,EAAW,SAAA,EAAA,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,GAAI,CAAC;AACrF,CAAC,EACH;AAEF,qBAAqB,CAAC,WAAW,GAAG,wBAAwB;;;;"}
package/Label.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { type HTMLAttributes, type ReactNode } from 'react';
2
+ export interface ChatBubbleLabelProps extends HTMLAttributes<HTMLDivElement> {
3
+ /** Имя отправителя */
4
+ children?: ReactNode;
5
+ }
6
+ /**
7
+ * Заголовок сообщения.
8
+ */
9
+ export declare const ChatBubbleLabel: import("react").ForwardRefExoticComponent<ChatBubbleLabelProps & import("react").RefAttributes<HTMLDivElement>>;
package/Label.js ADDED
@@ -0,0 +1,18 @@
1
+ import './index.css';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { forwardRef } from 'react';
4
+ import { getColors } from './internal/colors.js';
5
+ import { useChatBubbleMode } from './internal/mode.js';
6
+ import { Text } from '@hh.ru/magritte-ui-typography';
7
+
8
+ /**
9
+ * Заголовок сообщения.
10
+ */
11
+ const ChatBubbleLabel = forwardRef(({ children, ...props }, ref) => {
12
+ const colors = getColors(useChatBubbleMode());
13
+ return (jsx("div", { ...props, "data-qa": "chat-bubble-label", ref: ref, children: jsx(Text, { typography: "subtitle-2-semibold", style: colors.accentText, maxLines: 1, children: children }) }));
14
+ });
15
+ ChatBubbleLabel.displayName = 'ChatBubble.Label';
16
+
17
+ export { ChatBubbleLabel };
18
+ //# sourceMappingURL=Label.js.map
package/Label.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Label.js","sources":["src/Label.tsx"],"sourcesContent":["import { type HTMLAttributes, type ReactNode, forwardRef } from 'react';\n\nimport { getColors } from '@hh.ru/magritte-ui-chat-bubble/internal/colors';\nimport { useChatBubbleMode } from '@hh.ru/magritte-ui-chat-bubble/internal/mode';\nimport { Text } from '@hh.ru/magritte-ui-typography';\n\nexport interface ChatBubbleLabelProps extends HTMLAttributes<HTMLDivElement> {\n /** Имя отправителя */\n children?: ReactNode;\n}\n\n/**\n * Заголовок сообщения.\n */\nexport const ChatBubbleLabel = forwardRef<HTMLDivElement, ChatBubbleLabelProps>(({ children, ...props }, ref) => {\n const colors = getColors(useChatBubbleMode());\n\n return (\n <div {...props} data-qa=\"chat-bubble-label\" ref={ref}>\n <Text typography=\"subtitle-2-semibold\" style={colors.accentText} maxLines={1}>\n {children}\n </Text>\n </div>\n );\n});\n\nChatBubbleLabel.displayName = 'ChatBubble.Label';\n"],"names":["_jsx"],"mappings":";;;;;;AAWA;;AAEG;AACU,MAAA,eAAe,GAAG,UAAU,CAAuC,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,KAAI;AAC5G,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAE9C,IAAA,QACIA,GAAA,CAAA,KAAA,EAAA,EAAA,GAAS,KAAK,EAAA,SAAA,EAAU,mBAAmB,EAAC,GAAG,EAAE,GAAG,EAAA,QAAA,EAChDA,GAAC,CAAA,IAAI,IAAC,UAAU,EAAC,qBAAqB,EAAC,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,EACvE,QAAA,EAAA,QAAQ,EACN,CAAA,EAAA,CACL,EACR;AACN,CAAC,EAAE;AAEH,eAAe,CAAC,WAAW,GAAG,kBAAkB;;;;"}
package/Message.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
+ import { ChatBubbleMetaHostProps } from '@hh.ru/magritte-ui-chat-bubble/internal/utils';
3
+ export interface ChatBubbleMessageProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'>, ChatBubbleMetaHostProps {
4
+ /** Опциональный заголовок над текстом */
5
+ title?: ReactNode;
6
+ /** Текст сообщения */
7
+ children?: ReactNode;
8
+ }
9
+ export declare const ChatBubbleMessage: import("react").ForwardRefExoticComponent<ChatBubbleMessageProps & import("react").RefAttributes<HTMLDivElement>> & import("@hh.ru/magritte-ui-chat-bubble/internal/utils").MetaHostComponent;
package/Message.js ADDED
@@ -0,0 +1,22 @@
1
+ import './index.css';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { forwardRef } from 'react';
4
+ import { getColors } from './internal/colors.js';
5
+ import { useChatBubbleMode } from './internal/mode.js';
6
+ import { markMetaHost } from './internal/utils.js';
7
+ import { Text } from '@hh.ru/magritte-ui-typography';
8
+ import { s as styles } from './chat-bubble-Djyvds6I.js';
9
+
10
+ /**
11
+ * Текстовая часть сообщения.
12
+ * Время встаёт в одну строку с последней строкой текста (иначе переносится под текст)
13
+ */
14
+ const ChatBubbleMessageComponent = forwardRef(({ children, meta, title, ...props }, ref) => {
15
+ const colors = getColors(useChatBubbleMode());
16
+ return (jsxs("div", { ...props, className: styles.message, "data-qa": "chat-bubble-message", ref: ref, children: [title && (jsx("div", { className: styles.messageTitle, "data-qa": "chat-bubble-message-title", children: jsx(Text, { Element: "span", typography: "subtitle-2-semibold", style: colors.text, children: title }) })), jsx(Text, { Element: "span", typography: "label-3-regular", style: colors.text, children: children }), meta] }));
17
+ });
18
+ ChatBubbleMessageComponent.displayName = 'ChatBubble.Message';
19
+ const ChatBubbleMessage = markMetaHost(ChatBubbleMessageComponent);
20
+
21
+ export { ChatBubbleMessage };
22
+ //# sourceMappingURL=Message.js.map
package/Message.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Message.js","sources":["src/Message.tsx"],"sourcesContent":["import { forwardRef, HTMLAttributes, ReactNode } from 'react';\n\nimport { getColors } from '@hh.ru/magritte-ui-chat-bubble/internal/colors';\nimport { useChatBubbleMode } from '@hh.ru/magritte-ui-chat-bubble/internal/mode';\nimport { markMetaHost, ChatBubbleMetaHostProps } from '@hh.ru/magritte-ui-chat-bubble/internal/utils';\nimport { Text } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './chat-bubble.less';\n\nexport interface ChatBubbleMessageProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'>, ChatBubbleMetaHostProps {\n /** Опциональный заголовок над текстом */\n title?: ReactNode;\n /** Текст сообщения */\n children?: ReactNode;\n}\n\n/**\n * Текстовая часть сообщения.\n * Время встаёт в одну строку с последней строкой текста (иначе переносится под текст)\n */\nconst ChatBubbleMessageComponent = forwardRef<HTMLDivElement, ChatBubbleMessageProps>(\n ({ children, meta, title, ...props }, ref) => {\n const colors = getColors(useChatBubbleMode());\n\n return (\n <div {...props} className={styles.message} data-qa=\"chat-bubble-message\" ref={ref}>\n {title && (\n <div className={styles.messageTitle} data-qa=\"chat-bubble-message-title\">\n <Text Element=\"span\" typography=\"subtitle-2-semibold\" style={colors.text}>\n {title}\n </Text>\n </div>\n )}\n <Text Element=\"span\" typography=\"label-3-regular\" style={colors.text}>\n {children}\n </Text>\n {meta}\n </div>\n );\n }\n);\n\nChatBubbleMessageComponent.displayName = 'ChatBubble.Message';\n\nexport const ChatBubbleMessage = markMetaHost(ChatBubbleMessageComponent);\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;;;AAgBA;;;AAGG;AACH,MAAM,0BAA0B,GAAG,UAAU,CACzC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,KAAI;AACzC,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAE9C,IAAA,QACIA,IAAA,CAAA,KAAA,EAAA,EAAA,GAAS,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,aAAU,qBAAqB,EAAC,GAAG,EAAE,GAAG,EAC5E,QAAA,EAAA,CAAA,KAAK,KACFC,GAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,MAAM,CAAC,YAAY,EAAA,SAAA,EAAU,2BAA2B,EAAA,QAAA,EACpEA,IAAC,IAAI,EAAA,EAAC,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,qBAAqB,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAA,QAAA,EACnE,KAAK,EAAA,CACH,GACL,CACT,EACDA,GAAC,CAAA,IAAI,IAAC,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,iBAAiB,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAA,QAAA,EAC/D,QAAQ,EACN,CAAA,EACN,IAAI,CAAA,EAAA,CACH,EACR;AACN,CAAC,CACJ,CAAC;AAEF,0BAA0B,CAAC,WAAW,GAAG,oBAAoB,CAAC;MAEjD,iBAAiB,GAAG,YAAY,CAAC,0BAA0B;;;;"}
package/Status.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { ChatBubbleStatusValue } from '@hh.ru/magritte-ui-chat-bubble/types';
3
+ import { type TooltipHoverProps } from '@hh.ru/magritte-ui-tooltip';
4
+ export interface ChatBubbleStatusProps extends Omit<TooltipHoverProps, 'activatorRef' | 'placement' | 'size' | 'children'> {
5
+ /** Статус отправки. У сообщений от бота не используется — там всегда «видно только вам»
6
+ * @default sending
7
+ */
8
+ value?: ChatBubbleStatusValue;
9
+ /** Текст подсказки. По умолчанию берётся из словаря по статусу */
10
+ children?: ReactNode;
11
+ /** Значение data-qa
12
+ * @default chat-bubble-status
13
+ */
14
+ 'data-qa'?: string;
15
+ }
16
+ /**
17
+ * Статус сообщения: иконка и подсказка к ней.
18
+ */
19
+ export declare const ChatBubbleStatus: import("react").ForwardRefExoticComponent<ChatBubbleStatusProps & import("react").RefAttributes<HTMLSpanElement>>;
package/Status.js ADDED
@@ -0,0 +1,34 @@
1
+ import './index.css';
2
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
+ import { forwardRef, useRef } from 'react';
4
+ import { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';
5
+ import { useTranslation } from '@hh.ru/magritte-common-use-translation';
6
+ import { getColors } from './internal/colors.js';
7
+ import { useChatBubbleMode } from './internal/mode.js';
8
+ import { EyeOutlinedSize16, ClockOutlinedSize16, CheckOutlinedSize16, CheckDoubleOutlinedSize16 } from '@hh.ru/magritte-ui-icon/icon';
9
+ import { TooltipHover } from '@hh.ru/magritte-ui-tooltip';
10
+ import { s as styles } from './chat-bubble-Djyvds6I.js';
11
+
12
+ const ICON = {
13
+ sending: ClockOutlinedSize16,
14
+ sent: CheckOutlinedSize16,
15
+ delivered: CheckDoubleOutlinedSize16,
16
+ };
17
+ /**
18
+ * Статус сообщения: иконка и подсказка к ней.
19
+ */
20
+ const ChatBubbleStatus = forwardRef(({ children, 'data-qa': dataQa = 'chat-bubble-status', value = 'sending', ...tooltipProps }, ref) => {
21
+ const mode = useChatBubbleMode();
22
+ const colors = getColors(mode);
23
+ const activatorRef = useRef(null);
24
+ const activator = useMultipleRefs(ref, activatorRef);
25
+ const isBot = mode === 'bot';
26
+ const label = useTranslation('ChatBubble', isBot ? 'private' : value);
27
+ // у бота по макету всегда глаз, статус отправки к нему не применяется
28
+ const Icon = isBot ? EyeOutlinedSize16 : ICON[value];
29
+ return (jsxs(Fragment, { children: [jsx("span", { ref: activator, className: styles.status, "data-qa": dataQa, "data-status": isBot ? 'private' : value, children: jsx(Icon, { initialColor: colors.statusIcon, "aria-label": label }) }), jsx(TooltipHover, { ...tooltipProps, activatorRef: activatorRef, placement: "top-center", size: "small", children: children ?? label })] }));
30
+ });
31
+ ChatBubbleStatus.displayName = 'ChatBubble.Status';
32
+
33
+ export { ChatBubbleStatus };
34
+ //# sourceMappingURL=Status.js.map
package/Status.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Status.js","sources":["src/Status.tsx"],"sourcesContent":["import { forwardRef, useRef, type ReactNode } from 'react';\n\nimport { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';\nimport { useTranslation } from '@hh.ru/magritte-common-use-translation';\nimport { getColors } from '@hh.ru/magritte-ui-chat-bubble/internal/colors';\nimport { useChatBubbleMode } from '@hh.ru/magritte-ui-chat-bubble/internal/mode';\nimport type { ChatBubbleStatusValue } from '@hh.ru/magritte-ui-chat-bubble/types';\nimport {\n CheckDoubleOutlinedSize16,\n CheckOutlinedSize16,\n ClockOutlinedSize16,\n EyeOutlinedSize16,\n} from '@hh.ru/magritte-ui-icon/icon';\nimport { TooltipHover, type TooltipHoverProps } from '@hh.ru/magritte-ui-tooltip';\n\nimport styles from './chat-bubble.less';\n\nconst ICON = {\n sending: ClockOutlinedSize16,\n sent: CheckOutlinedSize16,\n delivered: CheckDoubleOutlinedSize16,\n} as const;\n\nexport interface ChatBubbleStatusProps\n extends Omit<TooltipHoverProps, 'activatorRef' | 'placement' | 'size' | 'children'> {\n /** Статус отправки. У сообщений от бота не используется — там всегда «видно только вам»\n * @default sending\n */\n value?: ChatBubbleStatusValue;\n /** Текст подсказки. По умолчанию берётся из словаря по статусу */\n children?: ReactNode;\n /** Значение data-qa\n * @default chat-bubble-status\n */\n 'data-qa'?: string;\n}\n\n/**\n * Статус сообщения: иконка и подсказка к ней.\n */\nexport const ChatBubbleStatus = forwardRef<HTMLSpanElement, ChatBubbleStatusProps>(\n ({ children, 'data-qa': dataQa = 'chat-bubble-status', value = 'sending', ...tooltipProps }, ref) => {\n const mode = useChatBubbleMode();\n const colors = getColors(mode);\n const activatorRef = useRef<HTMLSpanElement>(null);\n const activator = useMultipleRefs(ref, activatorRef);\n const isBot = mode === 'bot';\n const label = useTranslation('ChatBubble', isBot ? 'private' : value);\n\n // у бота по макету всегда глаз, статус отправки к нему не применяется\n const Icon = isBot ? EyeOutlinedSize16 : ICON[value];\n\n return (\n <>\n <span\n ref={activator}\n className={styles.status}\n data-qa={dataQa}\n data-status={isBot ? 'private' : value}\n >\n <Icon initialColor={colors.statusIcon} aria-label={label} />\n </span>\n <TooltipHover {...tooltipProps} activatorRef={activatorRef} placement=\"top-center\" size=\"small\">\n {children ?? label}\n </TooltipHover>\n </>\n );\n }\n);\n\nChatBubbleStatus.displayName = 'ChatBubble.Status';\n"],"names":["_jsxs","_Fragment","_jsx"],"mappings":";;;;;;;;;;AAiBA,MAAM,IAAI,GAAG;AACT,IAAA,OAAO,EAAE,mBAAmB;AAC5B,IAAA,IAAI,EAAE,mBAAmB;AACzB,IAAA,SAAS,EAAE,yBAAyB;CAC9B,CAAC;AAgBX;;AAEG;AACU,MAAA,gBAAgB,GAAG,UAAU,CACtC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,oBAAoB,EAAE,KAAK,GAAG,SAAS,EAAE,GAAG,YAAY,EAAE,EAAE,GAAG,KAAI;AAChG,IAAA,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;AACjC,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAC/B,IAAA,MAAM,YAAY,GAAG,MAAM,CAAkB,IAAI,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AACrD,IAAA,MAAM,KAAK,GAAG,IAAI,KAAK,KAAK,CAAC;AAC7B,IAAA,MAAM,KAAK,GAAG,cAAc,CAAC,YAAY,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,CAAC,CAAC;;AAGtE,IAAA,MAAM,IAAI,GAAG,KAAK,GAAG,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;AAErD,IAAA,QACIA,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACIC,GACI,CAAA,MAAA,EAAA,EAAA,GAAG,EAAE,SAAS,EACd,SAAS,EAAE,MAAM,CAAC,MAAM,EACf,SAAA,EAAA,MAAM,EACF,aAAA,EAAA,KAAK,GAAG,SAAS,GAAG,KAAK,EAEtC,QAAA,EAAAA,GAAA,CAAC,IAAI,EAAA,EAAC,YAAY,EAAE,MAAM,CAAC,UAAU,EAAA,YAAA,EAAc,KAAK,EAAA,CAAI,EACzD,CAAA,EACPA,GAAC,CAAA,YAAY,EAAK,EAAA,GAAA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAC,YAAY,EAAC,IAAI,EAAC,OAAO,EAC1F,QAAA,EAAA,QAAQ,IAAI,KAAK,EACP,CAAA,CAAA,EAAA,CAChB,EACL;AACN,CAAC,EACH;AAEF,gBAAgB,CAAC,WAAW,GAAG,mBAAmB;;;;"}
@@ -0,0 +1,5 @@
1
+ import './index.css';
2
+ var styles = {"tail":"magritte-tail___-1lJ0_1-1-0","tail_outgoing":"magritte-tail_outgoing___cnyh3_1-1-0","tailOutgoing":"magritte-tail_outgoing___cnyh3_1-1-0","meta":"magritte-meta___HT7lp_1-1-0"};
3
+
4
+ export { styles as s };
5
+ //# sourceMappingURL=chat-bubble-B2HOuNTb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-bubble-B2HOuNTb.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,5 @@
1
+ import './index.css';
2
+ var styles = {"chat-bubble":"magritte-chat-bubble___ds9CP_1-1-0","chatBubble":"magritte-chat-bubble___ds9CP_1-1-0","outgoing":"magritte-outgoing___3n00o_1-1-0","bot":"magritte-bot___Z6vZA_1-1-0","row":"magritte-row___mQNnt_1-1-0","bubble":"magritte-bubble___NVuDI_1-1-0","with-tail":"magritte-with-tail___IdixJ_1-1-0","withTail":"magritte-with-tail___IdixJ_1-1-0","header":"magritte-header___Px2to_1-1-0","message-title":"magritte-message-title___dgBFk_1-1-0","messageTitle":"magritte-message-title___dgBFk_1-1-0","message":"magritte-message___7TEpw_1-1-0","buttons":"magritte-buttons___yQqBi_1-1-0","actions":"magritte-actions___I5GSz_1-1-0","error-text":"magritte-error-text___1ZxWY_1-1-0","errorText":"magritte-error-text___1ZxWY_1-1-0","status":"magritte-status___dHzCt_1-1-0"};
3
+
4
+ export { styles as s };
5
+ //# sourceMappingURL=chat-bubble-Djyvds6I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-bubble-Djyvds6I.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
package/index.css ADDED
@@ -0,0 +1,134 @@
1
+ :root{
2
+ --magritte-color-component-chat-bubble-background-incoming-v25-0-1:#F4F6FB;
3
+ --magritte-color-component-chat-bubble-background-outgoing-v25-0-1:#0070ff;
4
+ --magritte-color-component-chat-bubble-background-bot-v25-0-1:#f9f7ff;
5
+ --magritte-color-component-chat-bubble-border-incoming-v25-0-1:#EEF1F7;
6
+ --magritte-color-component-chat-bubble-border-outgoing-v25-0-1:#0d63e3;
7
+ --magritte-color-component-chat-bubble-border-bot-v25-0-1:#f3eeff;
8
+ }
9
+
10
+ .magritte-night-theme{
11
+ --magritte-color-component-chat-bubble-background-incoming-v25-0-1:#262626;
12
+ --magritte-color-component-chat-bubble-background-outgoing-v25-0-1:#2b7fff;
13
+ --magritte-color-component-chat-bubble-background-bot-v25-0-1:#312F47;
14
+ --magritte-color-component-chat-bubble-border-incoming-v25-0-1:#303030;
15
+ --magritte-color-component-chat-bubble-border-outgoing-v25-0-1:#0070ff;
16
+ --magritte-color-component-chat-bubble-border-bot-v25-0-1:#403A59;
17
+ }
18
+
19
+ .magritte-zp-day-theme{
20
+ --magritte-color-component-chat-bubble-background-outgoing-v25-0-1:#7195AF;
21
+ --magritte-color-component-chat-bubble-border-outgoing-v25-0-1:#557B96;
22
+ }
23
+ .magritte-chat-bubble___ds9CP_1-1-0{
24
+ --magritte-chat-bubble-background:var(--magritte-color-component-chat-bubble-background-incoming-v25-0-1);
25
+ --magritte-chat-bubble-border:var(--magritte-color-component-chat-bubble-border-incoming-v25-0-1);
26
+ display:flex;
27
+ flex-direction:column;
28
+ align-items:flex-start;
29
+ max-width:calc(100% - 40px);
30
+ }
31
+ @media (min-width: 1020px){
32
+ body.magritte-old-layout .magritte-chat-bubble___ds9CP_1-1-0{
33
+ max-width:min(460px, 100%);
34
+ }
35
+ }
36
+ @media (min-width: 1024px){
37
+ body:not(.magritte-old-layout) .magritte-chat-bubble___ds9CP_1-1-0{
38
+ max-width:min(460px, 100%);
39
+ }
40
+ }
41
+ .magritte-outgoing___3n00o_1-1-0{
42
+ --magritte-chat-bubble-background:var(--magritte-color-component-chat-bubble-background-outgoing-v25-0-1);
43
+ --magritte-chat-bubble-border:var(--magritte-color-component-chat-bubble-border-outgoing-v25-0-1);
44
+ align-items:flex-end;
45
+ margin-left:auto;
46
+ }
47
+ .magritte-bot___Z6vZA_1-1-0{
48
+ --magritte-chat-bubble-background:var(--magritte-color-component-chat-bubble-background-bot-v25-0-1);
49
+ --magritte-chat-bubble-border:var(--magritte-color-component-chat-bubble-border-bot-v25-0-1);
50
+ }
51
+ .magritte-row___mQNnt_1-1-0{
52
+ display:flex;
53
+ align-items:flex-end;
54
+ gap:8px;
55
+ max-width:100%;
56
+ }
57
+ .magritte-bubble___NVuDI_1-1-0{
58
+ position:relative;
59
+ box-sizing:border-box;
60
+ min-width:0;
61
+ max-width:100%;
62
+ padding:12px;
63
+ background-color:var(--magritte-chat-bubble-background);
64
+ border:1px solid var(--magritte-chat-bubble-border);
65
+ border-radius:20px;
66
+ overflow-wrap:break-word;
67
+ }
68
+ .magritte-with-tail___IdixJ_1-1-0 .magritte-bubble___NVuDI_1-1-0{
69
+ border-bottom-left-radius:0;
70
+ }
71
+ .magritte-with-tail___IdixJ_1-1-0.magritte-outgoing___3n00o_1-1-0 .magritte-bubble___NVuDI_1-1-0{
72
+ border-bottom-left-radius:20px;
73
+ border-bottom-right-radius:0;
74
+ }
75
+ .magritte-header___Px2to_1-1-0{
76
+ display:flex;
77
+ flex-direction:column;
78
+ gap:4px;
79
+ margin-bottom:4px;
80
+ }
81
+ .magritte-message-title___dgBFk_1-1-0{
82
+ margin-bottom:4px;
83
+ }
84
+ .magritte-message___7TEpw_1-1-0:not(:first-child){
85
+ margin-top:8px;
86
+ }
87
+ .magritte-buttons___yQqBi_1-1-0{
88
+ display:grid;
89
+ grid-template-columns:repeat(2, 1fr);
90
+ gap:8px;
91
+ width:100%;
92
+ margin-top:4px;
93
+ }
94
+ .magritte-buttons___yQqBi_1-1-0 > *:last-child:nth-child(odd){
95
+ grid-column:span 2;
96
+ }
97
+ .magritte-actions___I5GSz_1-1-0{
98
+ display:flex;
99
+ flex-wrap:wrap;
100
+ gap:2px;
101
+ margin-top:4px;
102
+ }
103
+ .magritte-error-text___1ZxWY_1-1-0{
104
+ margin-top:2px;
105
+ }
106
+ .magritte-status___dHzCt_1-1-0{
107
+ display:inline-flex;
108
+ vertical-align:middle;
109
+ margin-left:4px;
110
+ }
111
+
112
+ .magritte-tail___-1lJ0_1-1-0{
113
+ position:absolute;
114
+ bottom:-1px;
115
+ left:-7px;
116
+ }
117
+ .magritte-tail_outgoing___cnyh3_1-1-0{
118
+ left:auto;
119
+ right:-7px;
120
+ transform:scaleX(-1);
121
+ }
122
+ .magritte-meta___HT7lp_1-1-0{
123
+ float:right;
124
+ margin-left:12px;
125
+ white-space:nowrap;
126
+ font-family:"hh sans";
127
+ font-weight:400;
128
+ line-height:20px;
129
+ font-size:14px;
130
+ letter-spacing:0.005em;
131
+ text-indent:0px;
132
+ text-transform:none;
133
+ text-decoration:none;
134
+ }
package/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export { ChatBubble } from '@hh.ru/magritte-ui-chat-bubble/ChatBubble';
2
+ export type { ChatBubbleMode, ChatBubbleStatusValue, ChatBubbleProps } from '@hh.ru/magritte-ui-chat-bubble/types';
3
+ export type { ChatBubbleErrorActionProps } from '@hh.ru/magritte-ui-chat-bubble/ErrorAction';
4
+ export type { ChatBubbleLabelProps } from '@hh.ru/magritte-ui-chat-bubble/Label';
5
+ export type { ChatBubbleMessageProps } from '@hh.ru/magritte-ui-chat-bubble/Message';
6
+ export type { ChatBubbleStatusProps } from '@hh.ru/magritte-ui-chat-bubble/Status';
package/index.js ADDED
@@ -0,0 +1,26 @@
1
+ import './index.css';
2
+ export { ChatBubble } from './ChatBubble.js';
3
+ import 'react/jsx-runtime';
4
+ import 'react';
5
+ import 'classnames';
6
+ import '@hh.ru/magritte-ui-button';
7
+ import './ErrorAction.js';
8
+ import './internal/errorMenu.js';
9
+ import '@hh.ru/magritte-ui-menu';
10
+ import './Label.js';
11
+ import './internal/colors.js';
12
+ import './internal/mode.js';
13
+ import '@hh.ru/magritte-ui-typography';
14
+ import './Message.js';
15
+ import './internal/utils.js';
16
+ import './chat-bubble-Djyvds6I.js';
17
+ import './Status.js';
18
+ import '@hh.ru/magritte-common-use-multiple-refs';
19
+ import '@hh.ru/magritte-common-use-translation';
20
+ import '@hh.ru/magritte-ui-icon/icon';
21
+ import '@hh.ru/magritte-ui-tooltip';
22
+ import './internal/Meta.js';
23
+ import './chat-bubble-B2HOuNTb.js';
24
+ import './internal/Tail.js';
25
+ import '@hh.ru/magritte-ui-icon';
26
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,11 @@
1
+ export type { ChatBubbleMode, ChatBubbleStatusValue, ChatBubbleProps } from '@hh.ru/magritte-ui-chat-bubble/types';
2
+ export type { ChatBubbleErrorActionProps } from '@hh.ru/magritte-ui-chat-bubble/ErrorAction';
3
+ export type { ChatBubbleLabelProps } from '@hh.ru/magritte-ui-chat-bubble/Label';
4
+ export type { ChatBubbleMessageProps } from '@hh.ru/magritte-ui-chat-bubble/Message';
5
+ export type { ChatBubbleStatusProps } from '@hh.ru/magritte-ui-chat-bubble/Status';
6
+ export declare const ChatBubble: import("react").ForwardRefExoticComponent<Record<string, unknown>> & {
7
+ ErrorAction: import("react").ForwardRefExoticComponent<Record<string, unknown>>;
8
+ Label: import("react").ForwardRefExoticComponent<Record<string, unknown>>;
9
+ Message: import("react").ForwardRefExoticComponent<Record<string, unknown>>;
10
+ Status: import("react").ForwardRefExoticComponent<Record<string, unknown>>;
11
+ };
package/index.mock.js ADDED
@@ -0,0 +1,16 @@
1
+ import './index.css';
2
+ import { mockComponent } from '@hh.ru/magritte-ui-mock-component';
3
+
4
+ const ErrorAction = mockComponent('ChatBubble.ErrorAction', undefined, { withChildren: true });
5
+ const Label = mockComponent('ChatBubble.Label', undefined, { withChildren: true });
6
+ const Message = mockComponent('ChatBubble.Message', undefined, { withChildren: true });
7
+ const Status = mockComponent('ChatBubble.Status', undefined, { withChildren: true });
8
+ const ChatBubble = Object.assign(mockComponent('ChatBubble', undefined, { withChildren: true }), {
9
+ ErrorAction,
10
+ Label,
11
+ Message,
12
+ Status,
13
+ });
14
+
15
+ export { ChatBubble };
16
+ //# sourceMappingURL=index.mock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mock.js","sources":["src/index.mock.ts"],"sourcesContent":["import { mockComponent } from '@hh.ru/magritte-ui-mock-component';\n\nexport type { ChatBubbleMode, ChatBubbleStatusValue, ChatBubbleProps } from '@hh.ru/magritte-ui-chat-bubble/types';\nexport type { ChatBubbleErrorActionProps } from '@hh.ru/magritte-ui-chat-bubble/ErrorAction';\nexport type { ChatBubbleLabelProps } from '@hh.ru/magritte-ui-chat-bubble/Label';\nexport type { ChatBubbleMessageProps } from '@hh.ru/magritte-ui-chat-bubble/Message';\nexport type { ChatBubbleStatusProps } from '@hh.ru/magritte-ui-chat-bubble/Status';\n\nconst ErrorAction = mockComponent('ChatBubble.ErrorAction', undefined, { withChildren: true });\nconst Label = mockComponent('ChatBubble.Label', undefined, { withChildren: true });\nconst Message = mockComponent('ChatBubble.Message', undefined, { withChildren: true });\nconst Status = mockComponent('ChatBubble.Status', undefined, { withChildren: true });\n\nexport const ChatBubble = Object.assign(mockComponent('ChatBubble', undefined, { withChildren: true }), {\n ErrorAction,\n Label,\n Message,\n Status,\n});\n"],"names":[],"mappings":";;AAQA,MAAM,WAAW,GAAG,aAAa,CAAC,wBAAwB,EAAE,SAAS,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/F,MAAM,KAAK,GAAG,aAAa,CAAC,kBAAkB,EAAE,SAAS,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;AACnF,MAAM,OAAO,GAAG,aAAa,CAAC,oBAAoB,EAAE,SAAS,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;AACvF,MAAM,MAAM,GAAG,aAAa,CAAC,mBAAmB,EAAE,SAAS,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;MAExE,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,YAAY,EAAE,SAAS,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE;IACpG,WAAW;IACX,KAAK;IACL,OAAO;IACP,MAAM;AACT,CAAA;;;;"}
@@ -0,0 +1,13 @@
1
+ import { type FC, type ReactNode } from 'react';
2
+ import type { ChatBubbleMode } from '@hh.ru/magritte-ui-chat-bubble/types';
3
+ interface MetaProps {
4
+ mode: ChatBubbleMode;
5
+ status?: ReactNode;
6
+ time?: ReactNode;
7
+ }
8
+ /**
9
+ * Время и статус сообщения
10
+ * Рендерится внутри последнего элемента контента.
11
+ * */
12
+ export declare const Meta: FC<MetaProps>;
13
+ export {};
@@ -0,0 +1,20 @@
1
+ import './../index.css';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { getColors } from './colors.js';
4
+ import { Text } from '@hh.ru/magritte-ui-typography';
5
+ import { s as styles } from '../chat-bubble-B2HOuNTb.js';
6
+
7
+ /**
8
+ * Время и статус сообщения
9
+ * Рендерится внутри последнего элемента контента.
10
+ * */
11
+ const Meta = ({ mode, status, time }) => {
12
+ const visibleStatus = mode === 'incoming' ? undefined : status;
13
+ if (!time && !visibleStatus) {
14
+ return null;
15
+ }
16
+ return (jsxs("span", { className: styles.meta, "data-qa": "chat-bubble-meta", children: [time && (jsx(Text, { Element: "span", typography: "label-4-regular", style: getColors(mode).secondaryText, children: time })), visibleStatus] }));
17
+ };
18
+
19
+ export { Meta };
20
+ //# sourceMappingURL=Meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Meta.js","sources":["src/internal/Meta.tsx"],"sourcesContent":["import { type FC, type ReactNode } from 'react';\n\nimport { getColors } from '@hh.ru/magritte-ui-chat-bubble/internal/colors';\nimport type { ChatBubbleMode } from '@hh.ru/magritte-ui-chat-bubble/types';\nimport { Text } from '@hh.ru/magritte-ui-typography';\n\nimport styles from './chat-bubble.less';\n\ninterface MetaProps {\n mode: ChatBubbleMode;\n status?: ReactNode;\n time?: ReactNode;\n}\n\n/**\n * Время и статус сообщения\n * Рендерится внутри последнего элемента контента.\n * */\nexport const Meta: FC<MetaProps> = ({ mode, status, time }) => {\n const visibleStatus = mode === 'incoming' ? undefined : status;\n\n if (!time && !visibleStatus) {\n return null;\n }\n\n return (\n <span className={styles.meta} data-qa=\"chat-bubble-meta\">\n {time && (\n <Text Element=\"span\" typography=\"label-4-regular\" style={getColors(mode).secondaryText}>\n {time}\n </Text>\n )}\n {visibleStatus}\n </span>\n );\n};\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;AAcA;;;AAGK;AACE,MAAM,IAAI,GAAkB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAI;AAC1D,IAAA,MAAM,aAAa,GAAG,IAAI,KAAK,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;AAE/D,IAAA,IAAI,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE;AACzB,QAAA,OAAO,IAAI,CAAC;KACf;AAED,IAAA,QACIA,IAAM,CAAA,MAAA,EAAA,EAAA,SAAS,EAAE,MAAM,CAAC,IAAI,EAAU,SAAA,EAAA,kBAAkB,EACnD,QAAA,EAAA,CAAA,IAAI,KACDC,GAAA,CAAC,IAAI,EAAC,EAAA,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,iBAAiB,EAAC,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,aAAa,EAAA,QAAA,EACjF,IAAI,EACF,CAAA,CACV,EACA,aAAa,CAAA,EAAA,CACX,EACT;AACN;;;;"}
@@ -0,0 +1,3 @@
1
+ import { type FC } from 'react';
2
+ /** Хвост сообщения */
3
+ export declare const Tail: FC;
@@ -0,0 +1,16 @@
1
+ import './../index.css';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import classnames from 'classnames';
4
+ import { useChatBubbleMode } from './mode.js';
5
+ import { s as styles } from '../chat-bubble-B2HOuNTb.js';
6
+ import 'react';
7
+
8
+ const OUTLINE = 'M6.5 0C6.5 7.5 5.2 11.8 1.6 13.4C0.9 13.9 0.6 14.5 1.1 14.5H7';
9
+ /** Хвост сообщения */
10
+ const Tail = () => {
11
+ const mode = useChatBubbleMode();
12
+ return (jsxs("svg", { className: classnames(styles.tail, { [styles.tailOutgoing]: mode === 'outgoing' }), xmlns: "http://www.w3.org/2000/svg", width: "7", height: "15", viewBox: "0 0 7 15", fill: "none", "aria-hidden": true, focusable: "false", children: [jsx("path", { d: `${OUTLINE}V0Z`, fill: "var(--magritte-chat-bubble-background)" }), jsx("path", { d: OUTLINE, stroke: "var(--magritte-chat-bubble-border)", strokeWidth: "1" })] }));
13
+ };
14
+
15
+ export { Tail };
16
+ //# sourceMappingURL=Tail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tail.js","sources":["src/internal/Tail.tsx"],"sourcesContent":["import { type FC } from 'react';\nimport classnames from 'classnames';\n\nimport { useChatBubbleMode } from '@hh.ru/magritte-ui-chat-bubble/internal/mode';\n\nimport styles from './chat-bubble.less';\n\nconst OUTLINE = 'M6.5 0C6.5 7.5 5.2 11.8 1.6 13.4C0.9 13.9 0.6 14.5 1.1 14.5H7';\n\n/** Хвост сообщения */\nexport const Tail: FC = () => {\n const mode = useChatBubbleMode();\n\n return (\n <svg\n className={classnames(styles.tail, { [styles.tailOutgoing]: mode === 'outgoing' })}\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"7\"\n height=\"15\"\n viewBox=\"0 0 7 15\"\n fill=\"none\"\n aria-hidden\n focusable=\"false\"\n >\n {/* Заливка заходит под границу баббла и перекрывает её в месте стыка */}\n <path d={`${OUTLINE}V0Z`} fill=\"var(--magritte-chat-bubble-background)\" />\n <path d={OUTLINE} stroke=\"var(--magritte-chat-bubble-border)\" strokeWidth=\"1\" />\n </svg>\n );\n};\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;AAOA,MAAM,OAAO,GAAG,+DAA+D,CAAC;AAEhF;AACO,MAAM,IAAI,GAAO,MAAK;AACzB,IAAA,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;AAEjC,IAAA,QACIA,IAAA,CAAA,KAAA,EAAA,EACI,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,KAAK,UAAU,EAAE,CAAC,EAClF,KAAK,EAAC,4BAA4B,EAClC,KAAK,EAAC,GAAG,EACT,MAAM,EAAC,IAAI,EACX,OAAO,EAAC,UAAU,EAClB,IAAI,EAAC,MAAM,EAAA,aAAA,EAAA,IAAA,EAEX,SAAS,EAAC,OAAO,EAGjB,QAAA,EAAA,CAAAC,GAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAE,CAAA,EAAG,OAAO,CAAA,GAAA,CAAK,EAAE,IAAI,EAAC,wCAAwC,EAAA,CAAG,EAC1EA,GAAM,CAAA,MAAA,EAAA,EAAA,CAAC,EAAE,OAAO,EAAE,MAAM,EAAC,oCAAoC,EAAC,WAAW,EAAC,GAAG,EAAG,CAAA,CAAA,EAAA,CAC9E,EACR;AACN;;;;"}
@@ -0,0 +1,19 @@
1
+ import type { ButtonStyle } from '@hh.ru/magritte-ui-button';
2
+ import type { ChatBubbleMode } from '@hh.ru/magritte-ui-chat-bubble/types';
3
+ import type { IconColor } from '@hh.ru/magritte-ui-icon';
4
+ import type { TextStyle } from '@hh.ru/magritte-ui-typography';
5
+ export interface ChatBubbleColors {
6
+ /** Основной текст сообщения */
7
+ text: TextStyle;
8
+ /** Второстепенный текст: время, размер файла, описание сниппета */
9
+ secondaryText: TextStyle;
10
+ /** Акцентный текст: имя отправителя, автор цитаты, заголовок сниппета */
11
+ accentText: TextStyle;
12
+ /** Иконка статуса, лежит на фоне баббла */
13
+ statusIcon: IconColor;
14
+ /** Иконки действий, лежат под бабблом на фоне страницы */
15
+ actionsIcon: IconColor;
16
+ /** Кнопки под бабблом */
17
+ button: ButtonStyle;
18
+ }
19
+ export declare const getColors: (mode: ChatBubbleMode) => ChatBubbleColors;
@@ -0,0 +1,31 @@
1
+ import './../index.css';
2
+ const COLORS = {
3
+ incoming: {
4
+ text: 'primary',
5
+ secondaryText: 'secondary',
6
+ accentText: 'accent',
7
+ statusIcon: 'constant',
8
+ actionsIcon: 'secondary',
9
+ button: 'neutral',
10
+ },
11
+ outgoing: {
12
+ text: 'constant',
13
+ secondaryText: 'constant',
14
+ accentText: 'constant',
15
+ statusIcon: 'constant',
16
+ actionsIcon: 'accent',
17
+ button: 'accent',
18
+ },
19
+ bot: {
20
+ text: 'primary',
21
+ secondaryText: 'secondary',
22
+ accentText: 'special',
23
+ statusIcon: 'special',
24
+ actionsIcon: 'special',
25
+ button: 'special',
26
+ },
27
+ };
28
+ const getColors = (mode) => COLORS[mode];
29
+
30
+ export { getColors };
31
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sources":["src/internal/colors.ts"],"sourcesContent":["import type { ButtonStyle } from '@hh.ru/magritte-ui-button';\nimport type { ChatBubbleMode } from '@hh.ru/magritte-ui-chat-bubble/types';\nimport type { IconColor } from '@hh.ru/magritte-ui-icon';\nimport type { TextStyle } from '@hh.ru/magritte-ui-typography';\n\nexport interface ChatBubbleColors {\n /** Основной текст сообщения */\n text: TextStyle;\n /** Второстепенный текст: время, размер файла, описание сниппета */\n secondaryText: TextStyle;\n /** Акцентный текст: имя отправителя, автор цитаты, заголовок сниппета */\n accentText: TextStyle;\n /** Иконка статуса, лежит на фоне баббла */\n statusIcon: IconColor;\n /** Иконки действий, лежат под бабблом на фоне страницы */\n actionsIcon: IconColor;\n /** Кнопки под бабблом */\n button: ButtonStyle;\n}\n\nconst COLORS: Record<ChatBubbleMode, ChatBubbleColors> = {\n incoming: {\n text: 'primary',\n secondaryText: 'secondary',\n accentText: 'accent',\n statusIcon: 'constant',\n actionsIcon: 'secondary',\n button: 'neutral',\n },\n outgoing: {\n text: 'constant',\n secondaryText: 'constant',\n accentText: 'constant',\n statusIcon: 'constant',\n actionsIcon: 'accent',\n button: 'accent',\n },\n bot: {\n text: 'primary',\n secondaryText: 'secondary',\n accentText: 'special',\n statusIcon: 'special',\n actionsIcon: 'special',\n button: 'special',\n },\n};\n\nexport const getColors = (mode: ChatBubbleMode): ChatBubbleColors => COLORS[mode];\n"],"names":[],"mappings":"AAoBA,MAAM,MAAM,GAA6C;AACrD,IAAA,QAAQ,EAAE;AACN,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,aAAa,EAAE,WAAW;AAC1B,QAAA,UAAU,EAAE,QAAQ;AACpB,QAAA,UAAU,EAAE,UAAU;AACtB,QAAA,WAAW,EAAE,WAAW;AACxB,QAAA,MAAM,EAAE,SAAS;AACpB,KAAA;AACD,IAAA,QAAQ,EAAE;AACN,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,aAAa,EAAE,UAAU;AACzB,QAAA,UAAU,EAAE,UAAU;AACtB,QAAA,UAAU,EAAE,UAAU;AACtB,QAAA,WAAW,EAAE,QAAQ;AACrB,QAAA,MAAM,EAAE,QAAQ;AACnB,KAAA;AACD,IAAA,GAAG,EAAE;AACD,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,aAAa,EAAE,WAAW;AAC1B,QAAA,UAAU,EAAE,SAAS;AACrB,QAAA,UAAU,EAAE,SAAS;AACrB,QAAA,WAAW,EAAE,SAAS;AACtB,QAAA,MAAM,EAAE,SAAS;AACpB,KAAA;CACJ,CAAC;AAEK,MAAM,SAAS,GAAG,CAAC,IAAoB,KAAuB,MAAM,CAAC,IAAI;;;;"}
@@ -0,0 +1,2 @@
1
+ export declare const ChatBubbleErrorMenuProvider: import("react").Provider<VoidFunction>;
2
+ export declare const useChatBubbleErrorMenuClose: () => VoidFunction;
@@ -0,0 +1,10 @@
1
+ import './../index.css';
2
+ import { createContext, useContext } from 'react';
3
+
4
+ const noop = () => undefined;
5
+ const ChatBubbleErrorMenuContext = createContext(noop);
6
+ const ChatBubbleErrorMenuProvider = ChatBubbleErrorMenuContext.Provider;
7
+ const useChatBubbleErrorMenuClose = () => useContext(ChatBubbleErrorMenuContext);
8
+
9
+ export { ChatBubbleErrorMenuProvider, useChatBubbleErrorMenuClose };
10
+ //# sourceMappingURL=errorMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorMenu.js","sources":["src/internal/errorMenu.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nconst noop = () => undefined;\n\nconst ChatBubbleErrorMenuContext = createContext<VoidFunction>(noop);\n\nexport const ChatBubbleErrorMenuProvider = ChatBubbleErrorMenuContext.Provider;\n\nexport const useChatBubbleErrorMenuClose = (): VoidFunction => useContext(ChatBubbleErrorMenuContext);\n"],"names":[],"mappings":";;AAEA,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC;AAE7B,MAAM,0BAA0B,GAAG,aAAa,CAAe,IAAI,CAAC,CAAC;AAExD,MAAA,2BAA2B,GAAG,0BAA0B,CAAC,SAAS;AAElE,MAAA,2BAA2B,GAAG,MAAoB,UAAU,CAAC,0BAA0B;;;;"}
@@ -0,0 +1,4 @@
1
+ import type { ChatBubbleMode } from '@hh.ru/magritte-ui-chat-bubble/types';
2
+ /** Прокидывает режим баббла в подкомпоненты: от него зависят цвета текста и иконок. */
3
+ export declare const ChatBubbleModeProvider: import("react").Provider<ChatBubbleMode>;
4
+ export declare const useChatBubbleMode: () => ChatBubbleMode;
@@ -0,0 +1,10 @@
1
+ import './../index.css';
2
+ import { createContext, useContext } from 'react';
3
+
4
+ const ChatBubbleModeContext = createContext('incoming');
5
+ /** Прокидывает режим баббла в подкомпоненты: от него зависят цвета текста и иконок. */
6
+ const ChatBubbleModeProvider = ChatBubbleModeContext.Provider;
7
+ const useChatBubbleMode = () => useContext(ChatBubbleModeContext);
8
+
9
+ export { ChatBubbleModeProvider, useChatBubbleMode };
10
+ //# sourceMappingURL=mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode.js","sources":["src/internal/mode.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nimport type { ChatBubbleMode } from '@hh.ru/magritte-ui-chat-bubble/types';\n\nconst ChatBubbleModeContext = createContext<ChatBubbleMode>('incoming');\n\n/** Прокидывает режим баббла в подкомпоненты: от него зависят цвета текста и иконок. */\nexport const ChatBubbleModeProvider = ChatBubbleModeContext.Provider;\n\nexport const useChatBubbleMode = (): ChatBubbleMode => useContext(ChatBubbleModeContext);\n"],"names":[],"mappings":";;AAIA,MAAM,qBAAqB,GAAG,aAAa,CAAiB,UAAU,CAAC,CAAC;AAExE;AACa,MAAA,sBAAsB,GAAG,qBAAqB,CAAC,SAAS;AAExD,MAAA,iBAAiB,GAAG,MAAsB,UAAU,CAAC,qBAAqB;;;;"}
@@ -0,0 +1,11 @@
1
+ import { type ReactElement, type ReactNode } from 'react';
2
+ /** Помечает подкомпонент как умеющий принять слот времени и статуса */
3
+ export interface ChatBubbleMetaHostProps {
4
+ meta?: ReactNode;
5
+ }
6
+ export interface MetaHostComponent {
7
+ hostsMeta: true;
8
+ }
9
+ export declare const markMetaHost: <T extends object>(component: T) => T & MetaHostComponent;
10
+ export declare const isMetaHost: (node: ReactNode) => node is ReactElement<ChatBubbleMetaHostProps>;
11
+ export declare const flattenFragments: (children: ReactNode, keyPrefix?: string) => ReactNode[];
@@ -0,0 +1,18 @@
1
+ import './../index.css';
2
+ import { isValidElement, Children, Fragment, cloneElement } from 'react';
3
+
4
+ const markMetaHost = (component) => Object.assign(component, { hostsMeta: true });
5
+ const isMetaHost = (node) => isValidElement(node) && typeof node.type === 'object' && 'hostsMeta' in node.type;
6
+ const flattenFragments = (children, keyPrefix = '') => Children.toArray(children).flatMap((child) => {
7
+ if (!isValidElement(child)) {
8
+ return child;
9
+ }
10
+ const key = `${keyPrefix}${String(child.key)}`;
11
+ if (child.type === Fragment) {
12
+ return flattenFragments(child.props.children, key);
13
+ }
14
+ return keyPrefix ? cloneElement(child, { key }) : child;
15
+ });
16
+
17
+ export { flattenFragments, isMetaHost, markMetaHost };
18
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sources":["src/internal/utils.ts"],"sourcesContent":["import { Children, Fragment, cloneElement, isValidElement, type ReactElement, type ReactNode } from 'react';\n\n/** Помечает подкомпонент как умеющий принять слот времени и статуса */\nexport interface ChatBubbleMetaHostProps {\n meta?: ReactNode;\n}\n\nexport interface MetaHostComponent {\n hostsMeta: true;\n}\n\nexport const markMetaHost = <T extends object>(component: T): T & MetaHostComponent =>\n Object.assign(component, { hostsMeta: true } as const);\n\nexport const isMetaHost = (node: ReactNode): node is ReactElement<ChatBubbleMetaHostProps> =>\n isValidElement(node) && typeof node.type === 'object' && 'hostsMeta' in (node.type as object);\n\nexport const flattenFragments = (children: ReactNode, keyPrefix = ''): ReactNode[] =>\n Children.toArray(children).flatMap((child) => {\n if (!isValidElement(child)) {\n return child;\n }\n\n const key = `${keyPrefix}${String(child.key)}`;\n\n if (child.type === Fragment) {\n return flattenFragments((child.props as { children?: ReactNode }).children, key);\n }\n\n return keyPrefix ? cloneElement(child, { key }) : child;\n });\n"],"names":[],"mappings":";;MAWa,YAAY,GAAG,CAAmB,SAAY,KACvD,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAW,EAAE;AAE9C,MAAA,UAAU,GAAG,CAAC,IAAe,KACtC,cAAc,CAAC,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,WAAW,IAAK,IAAI,CAAC,KAAgB;AAErF,MAAA,gBAAgB,GAAG,CAAC,QAAmB,EAAE,SAAS,GAAG,EAAE,KAChE,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;AACzC,IAAA,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE;AACxB,QAAA,OAAO,KAAK,CAAC;KAChB;AAED,IAAA,MAAM,GAAG,GAAG,CAAG,EAAA,SAAS,CAAG,EAAA,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA,CAAE,CAAC;AAE/C,IAAA,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE;QACzB,OAAO,gBAAgB,CAAE,KAAK,CAAC,KAAkC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;KACpF;AAED,IAAA,OAAO,SAAS,GAAG,YAAY,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;AAC5D,CAAC;;;;"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@hh.ru/magritte-ui-chat-bubble",
3
+ "version": "1.1.0",
4
+ "main": "index.js",
5
+ "types": "index.d.ts",
6
+ "sideEffects": [
7
+ "index.css"
8
+ ],
9
+ "scripts": {
10
+ "build": "yarn root:build $(pwd)",
11
+ "build-test-branch": "yarn root:build-test-branch $(pwd)",
12
+ "prepack": "yarn root:prepack $(pwd)",
13
+ "postpublish": "yarn root:postpublish $(pwd)",
14
+ "stylelint-check": "yarn root:stylelint-check $(pwd)",
15
+ "eslint-check": "yarn root:eslint-check $(pwd)",
16
+ "ts-config": "yarn root:ts-config $(pwd)",
17
+ "ts-check": "yarn root:ts-check $(pwd)",
18
+ "test": "yarn root:test $(pwd)",
19
+ "watch": "yarn root:watch $(pwd)"
20
+ },
21
+ "dependencies": {
22
+ "@hh.ru/magritte-common-use-multiple-refs": "1.1.11",
23
+ "@hh.ru/magritte-common-use-translation": "3.3.0",
24
+ "@hh.ru/magritte-design-tokens": "25.0.1",
25
+ "@hh.ru/magritte-ui-breakpoint": "6.1.1",
26
+ "@hh.ru/magritte-ui-button": "7.3.0",
27
+ "@hh.ru/magritte-ui-icon": "15.0.3",
28
+ "@hh.ru/magritte-ui-menu": "1.0.32",
29
+ "@hh.ru/magritte-ui-mock-component": "1.1.7",
30
+ "@hh.ru/magritte-ui-tooltip": "11.0.44",
31
+ "@hh.ru/magritte-ui-typography": "5.3.12"
32
+ },
33
+ "peerDependencies": {
34
+ "classnames": ">=2.3.2",
35
+ "react": ">=18.2.0"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "gitHead": "ca6dd4b6ab147bf47045aa7608e7b6f60df53749"
41
+ }
package/types.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ /** Тип сообщения */
3
+ export type ChatBubbleMode = 'incoming' | 'outgoing' | 'bot';
4
+ /** Статус исходящего сообщения */
5
+ export type ChatBubbleStatusValue = 'sending' | 'sent' | 'delivered';
6
+ export interface ChatBubbleProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
7
+ /**
8
+ * Тип сообщения по отправителю
9
+ * @default incoming
10
+ */
11
+ mode?: ChatBubbleMode;
12
+ /**
13
+ * Верхняя часть сообщения: `ChatBubble.Label` и/или `ChatBubble.Reply`
14
+ */
15
+ header?: ReactNode;
16
+ /**
17
+ * Хвостик у баббла (показывается у одиночного сообщения/у последнего в группе)
18
+ * @default false
19
+ */
20
+ showTail?: boolean;
21
+ /** Время отправки */
22
+ time?: ReactNode;
23
+ /** Статус сообщения: `ChatBubble.Status`. У входящих сообщений статусов нет */
24
+ status?: ReactNode;
25
+ /** Дополнительные действия с сообщением: список иконок размера 16px под бабблом */
26
+ actions?: ReactNode;
27
+ /** Кнопки под бабблом. Доступны только у входящих сообщений и сообщений от бота */
28
+ buttons?: ReactNode;
29
+ /** Ошибка отправки. Показывается только у исходящего сообщения */
30
+ error?: boolean;
31
+ /** Текст ошибки под сообщением */
32
+ errorText?: ReactNode;
33
+ /**
34
+ * Действия для исправления ошибки: список `ChatBubble.ErrorAction`.
35
+ */
36
+ errorActions?: ReactNode;
37
+ /**
38
+ * Содержимое сообщения
39
+ * - текст и/или `ChatBubble.Reactions`
40
+ * - `ChatBubble.Media`
41
+ * - `ChatBubble.File`
42
+ * - `ChatBubble.Snippet`
43
+ */
44
+ children?: ReactNode;
45
+ /**
46
+ * Значение data-qa на корневом элементе
47
+ * @default chat-bubble
48
+ */
49
+ 'data-qa'?: string;
50
+ }
package/types.js ADDED
@@ -0,0 +1,3 @@
1
+ import './index.css';
2
+
3
+ //# sourceMappingURL=types.js.map
package/types.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}