@gravity-ui/aikit 2.18.0 → 2.18.1-beta.ba4014635335112dceef11e737ce8d0845e5935b.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 (69) hide show
  1. package/build/cjs/components/atoms/ActionButton/ActionButton.js +3 -16
  2. package/build/cjs/components/atoms/ActionButton/ActionButton.js.map +1 -1
  3. package/build/cjs/components/atoms/ChatDate/ChatDate.d.ts +0 -5
  4. package/build/cjs/components/atoms/ChatDate/ChatDate.js +1 -3
  5. package/build/cjs/components/atoms/ChatDate/ChatDate.js.map +1 -1
  6. package/build/cjs/components/atoms/ContextIndicator/ContextIndicator.css +1 -1
  7. package/build/cjs/components/molecules/PromptInputFooter/PromptInputFooter.css +1 -1
  8. package/build/cjs/components/organisms/Header/Header.js +10 -9
  9. package/build/cjs/components/organisms/Header/Header.js.map +1 -1
  10. package/build/cjs/components/organisms/Header/types.d.ts +1 -3
  11. package/build/cjs/components/organisms/Header/types.js.map +1 -1
  12. package/build/cjs/components/organisms/Header/useHeader.d.ts +0 -1
  13. package/build/cjs/components/organisms/Header/useHeader.js +1 -2
  14. package/build/cjs/components/organisms/Header/useHeader.js.map +1 -1
  15. package/build/cjs/components/organisms/MessageList/MessageList.css +1 -1
  16. package/build/cjs/components/templates/EmptyContainer/EmptyContainer.css +2 -2
  17. package/build/cjs/components/templates/History/DateHeaderItem.d.ts +1 -5
  18. package/build/cjs/components/templates/History/DateHeaderItem.js +2 -2
  19. package/build/cjs/components/templates/History/DateHeaderItem.js.map +1 -1
  20. package/build/cjs/components/templates/History/HistoryList.d.ts +0 -7
  21. package/build/cjs/components/templates/History/HistoryList.js +2 -2
  22. package/build/cjs/components/templates/History/HistoryList.js.map +1 -1
  23. package/build/cjs/hooks/useDateFormatter/index.d.ts +2 -5
  24. package/build/cjs/hooks/useDateFormatter/index.js +17 -34
  25. package/build/cjs/hooks/useDateFormatter/index.js.map +1 -1
  26. package/build/cjs/package.json +1 -1
  27. package/build/cjs/themes/common.css +0 -5
  28. package/build/cjs/themes/variables.css +0 -5
  29. package/build/docs/components/atoms/ChatDate.md +11 -13
  30. package/build/docs/components/organisms/Header.md +0 -1
  31. package/build/docs/components/organisms/MessageList.md +0 -6
  32. package/build/docs/components/templates/EmptyContainer.md +17 -23
  33. package/build/docs/components/templates/History.md +0 -10
  34. package/build/docs/guides/EXAMPLES.md +13 -83
  35. package/build/docs/guides/I18N.md +2 -2
  36. package/build/docs/guides/THEMING.md +6 -7
  37. package/build/esm/components/atoms/ActionButton/ActionButton.js +3 -16
  38. package/build/esm/components/atoms/ActionButton/ActionButton.js.map +1 -1
  39. package/build/esm/components/atoms/ChatDate/ChatDate.d.ts +0 -5
  40. package/build/esm/components/atoms/ChatDate/ChatDate.js +1 -3
  41. package/build/esm/components/atoms/ChatDate/ChatDate.js.map +1 -1
  42. package/build/esm/components/atoms/ContextIndicator/ContextIndicator.css +1 -1
  43. package/build/esm/components/molecules/PromptInputFooter/PromptInputFooter.css +1 -1
  44. package/build/esm/components/organisms/Header/Header.js +10 -9
  45. package/build/esm/components/organisms/Header/Header.js.map +1 -1
  46. package/build/esm/components/organisms/Header/types.d.ts +1 -3
  47. package/build/esm/components/organisms/Header/types.js.map +1 -1
  48. package/build/esm/components/organisms/Header/useHeader.d.ts +0 -1
  49. package/build/esm/components/organisms/Header/useHeader.js +1 -2
  50. package/build/esm/components/organisms/Header/useHeader.js.map +1 -1
  51. package/build/esm/components/organisms/MessageList/MessageList.css +1 -1
  52. package/build/esm/components/templates/EmptyContainer/EmptyContainer.css +2 -2
  53. package/build/esm/components/templates/History/DateHeaderItem.d.ts +1 -5
  54. package/build/esm/components/templates/History/DateHeaderItem.js +2 -2
  55. package/build/esm/components/templates/History/DateHeaderItem.js.map +1 -1
  56. package/build/esm/components/templates/History/HistoryList.d.ts +0 -7
  57. package/build/esm/components/templates/History/HistoryList.js +2 -2
  58. package/build/esm/components/templates/History/HistoryList.js.map +1 -1
  59. package/build/esm/hooks/useDateFormatter/index.d.ts +2 -5
  60. package/build/esm/hooks/useDateFormatter/index.js +17 -34
  61. package/build/esm/hooks/useDateFormatter/index.js.map +1 -1
  62. package/build/esm/package.json +1 -1
  63. package/build/esm/themes/common.css +0 -5
  64. package/build/esm/themes/variables.css +0 -5
  65. package/docs/EXAMPLES.md +13 -83
  66. package/docs/I18N.md +2 -2
  67. package/docs/THEMING.md +6 -7
  68. package/llms-full.txt +27 -110
  69. package/package.json +1 -1
@@ -16,26 +16,13 @@ const uikit_1 = require("@gravity-ui/uikit");
16
16
  * @returns ActionButton component
17
17
  */
18
18
  exports.ActionButton = react_1.default.forwardRef((_a, ref) => {
19
- var { tooltipTitle, tooltipPlacement, tooltipDisabled, tooltipOpenDelay, tooltipCloseDelay, wrapperClassName, className, children, onClick, onMouseLeave, onBlur } = _a, buttonProps = tslib_1.__rest(_a, ["tooltipTitle", "tooltipPlacement", "tooltipDisabled", "tooltipOpenDelay", "tooltipCloseDelay", "wrapperClassName", "className", "children", "onClick", "onMouseLeave", "onBlur"]);
20
- const [tooltipDismissed, setTooltipDismissed] = react_1.default.useState(false);
21
- const handleClick = (event) => {
22
- setTooltipDismissed(true);
23
- onClick === null || onClick === void 0 ? void 0 : onClick(event);
24
- };
25
- const handleMouseLeave = (event) => {
26
- setTooltipDismissed(false);
27
- onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave(event);
28
- };
29
- const handleBlur = (event) => {
30
- setTooltipDismissed(false);
31
- onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
32
- };
33
- const button = ((0, jsx_runtime_1.jsx)(uikit_1.Button, Object.assign({}, buttonProps, { ref: ref, className: className, onClick: handleClick, onMouseLeave: handleMouseLeave, onBlur: handleBlur, children: children })));
19
+ var { tooltipTitle, tooltipPlacement, tooltipDisabled, tooltipOpenDelay, tooltipCloseDelay, wrapperClassName, className, children } = _a, buttonProps = tslib_1.__rest(_a, ["tooltipTitle", "tooltipPlacement", "tooltipDisabled", "tooltipOpenDelay", "tooltipCloseDelay", "wrapperClassName", "className", "children"]);
20
+ const button = ((0, jsx_runtime_1.jsx)(uikit_1.Button, Object.assign({}, buttonProps, { ref: ref, className: className, children: children })));
34
21
  // If no tooltip props provided, return button without tooltip
35
22
  if (!tooltipTitle) {
36
23
  return button;
37
24
  }
38
- return ((0, jsx_runtime_1.jsx)(uikit_1.ActionTooltip, { title: tooltipTitle, placement: tooltipPlacement, disabled: tooltipDisabled || tooltipDismissed, openDelay: tooltipOpenDelay, closeDelay: tooltipCloseDelay, className: wrapperClassName, children: button }));
25
+ return ((0, jsx_runtime_1.jsx)(uikit_1.ActionTooltip, { title: tooltipTitle, placement: tooltipPlacement, disabled: tooltipDisabled, openDelay: tooltipOpenDelay, closeDelay: tooltipCloseDelay, className: wrapperClassName, children: button }));
39
26
  });
40
27
  exports.ActionButton.displayName = 'ActionButton';
41
28
  //# sourceMappingURL=ActionButton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ActionButton.js","sourceRoot":"../../../../../src","sources":["components/atoms/ActionButton/ActionButton.tsx"],"names":[],"mappings":";;;;;AAAA,0DAA0B;AAE1B,6CAA+F;AAqC/F;;;;;;;;;GASG;AACU,QAAA,YAAY,GAAG,eAAK,CAAC,UAAU,CACxC,CACI,EAaC,EACD,GAAG,EACL,EAAE;QAfA,EACI,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,EACT,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,MAAM,OAET,EADM,WAAW,sBAZlB,kLAaC,CADiB;IAIlB,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,eAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEtE,MAAM,WAAW,GAAG,CAAC,KAA0C,EAAE,EAAE;QAC/D,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAG,KAAK,CAAC,CAAC;IACrB,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,CAAC,KAA0C,EAAE,EAAE;QACpE,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC3B,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,KAAK,CAAC,CAAC;IAC1B,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,KAA0C,EAAE,EAAE;QAC9D,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAG,KAAK,CAAC,CAAC;IACpB,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CACX,uBAAC,cAAM,oBACC,WAAW,IACf,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,WAAW,EACpB,YAAY,EAAE,gBAAgB,EAC9B,MAAM,EAAE,UAAU,YAEjB,QAAQ,IACJ,CACZ,CAAC;IAEF,8DAA8D;IAC9D,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,OAAO,CACH,uBAAC,qBAAa,IACV,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,eAAe,IAAI,gBAAgB,EAC7C,SAAS,EAAE,gBAAgB,EAC3B,UAAU,EAAE,iBAAiB,EAC7B,SAAS,EAAE,gBAAgB,YAE1B,MAAM,GACK,CACnB,CAAC;AACN,CAAC,CACJ,CAAC;AAEF,oBAAY,CAAC,WAAW,GAAG,cAAc,CAAC","sourcesContent":["import React from 'react';\n\nimport {ActionTooltip, ActionTooltipProps, Button, ButtonButtonProps} from '@gravity-ui/uikit';\n\nexport interface ActionButtonProps extends Omit<ButtonButtonProps, 'className'> {\n /**\n * Button content (icon, text, or any ReactNode)\n */\n children?: React.ReactNode;\n /**\n * Additional CSS class for the button\n */\n className?: string;\n /**\n * Tooltip title text\n */\n tooltipTitle?: ActionTooltipProps['title'];\n /**\n * Tooltip placement\n */\n tooltipPlacement?: ActionTooltipProps['placement'];\n /**\n * Tooltip disabled state\n */\n tooltipDisabled?: ActionTooltipProps['disabled'];\n /**\n * Tooltip open delay in ms\n */\n tooltipOpenDelay?: ActionTooltipProps['openDelay'];\n /**\n * Tooltip close delay in ms\n */\n tooltipCloseDelay?: ActionTooltipProps['closeDelay'];\n /**\n * Additional CSS class for the wrapper\n */\n wrapperClassName?: string;\n}\n\n/**\n * ActionButton component combines Button with ActionTooltip\n *\n * This component wraps a Button inside an ActionTooltip, providing\n * a convenient way to add tooltips to action buttons throughout the application.\n *\n * @param props - Component props\n * @param ref - Forwarded ref to the button element\n * @returns ActionButton component\n */\nexport const ActionButton = React.forwardRef<HTMLButtonElement, ActionButtonProps>(\n (\n {\n tooltipTitle,\n tooltipPlacement,\n tooltipDisabled,\n tooltipOpenDelay,\n tooltipCloseDelay,\n wrapperClassName,\n className,\n children,\n onClick,\n onMouseLeave,\n onBlur,\n ...buttonProps\n },\n ref,\n ) => {\n const [tooltipDismissed, setTooltipDismissed] = React.useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setTooltipDismissed(true);\n onClick?.(event);\n };\n\n const handleMouseLeave = (event: React.MouseEvent<HTMLButtonElement>) => {\n setTooltipDismissed(false);\n onMouseLeave?.(event);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLButtonElement>) => {\n setTooltipDismissed(false);\n onBlur?.(event);\n };\n\n const button = (\n <Button\n {...buttonProps}\n ref={ref}\n className={className}\n onClick={handleClick}\n onMouseLeave={handleMouseLeave}\n onBlur={handleBlur}\n >\n {children}\n </Button>\n );\n\n // If no tooltip props provided, return button without tooltip\n if (!tooltipTitle) {\n return button;\n }\n\n return (\n <ActionTooltip\n title={tooltipTitle}\n placement={tooltipPlacement}\n disabled={tooltipDisabled || tooltipDismissed}\n openDelay={tooltipOpenDelay}\n closeDelay={tooltipCloseDelay}\n className={wrapperClassName}\n >\n {button}\n </ActionTooltip>\n );\n },\n);\n\nActionButton.displayName = 'ActionButton';\n"]}
1
+ {"version":3,"file":"ActionButton.js","sourceRoot":"../../../../../src","sources":["components/atoms/ActionButton/ActionButton.tsx"],"names":[],"mappings":";;;;;AAAA,0DAA0B;AAE1B,6CAA+F;AAqC/F;;;;;;;;;GASG;AACU,QAAA,YAAY,GAAG,eAAK,CAAC,UAAU,CACxC,CACI,EAUC,EACD,GAAG,EACL,EAAE;QAZA,EACI,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,SAAS,EACT,QAAQ,OAEX,EADM,WAAW,sBATlB,6IAUC,CADiB;IAIlB,MAAM,MAAM,GAAG,CACX,uBAAC,cAAM,oBAAK,WAAW,IAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,YAClD,QAAQ,IACJ,CACZ,CAAC;IAEF,8DAA8D;IAC9D,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,OAAO,CACH,uBAAC,qBAAa,IACV,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE,gBAAgB,EAC3B,UAAU,EAAE,iBAAiB,EAC7B,SAAS,EAAE,gBAAgB,YAE1B,MAAM,GACK,CACnB,CAAC;AACN,CAAC,CACJ,CAAC;AAEF,oBAAY,CAAC,WAAW,GAAG,cAAc,CAAC","sourcesContent":["import React from 'react';\n\nimport {ActionTooltip, ActionTooltipProps, Button, ButtonButtonProps} from '@gravity-ui/uikit';\n\nexport interface ActionButtonProps extends Omit<ButtonButtonProps, 'className'> {\n /**\n * Button content (icon, text, or any ReactNode)\n */\n children?: React.ReactNode;\n /**\n * Additional CSS class for the button\n */\n className?: string;\n /**\n * Tooltip title text\n */\n tooltipTitle?: ActionTooltipProps['title'];\n /**\n * Tooltip placement\n */\n tooltipPlacement?: ActionTooltipProps['placement'];\n /**\n * Tooltip disabled state\n */\n tooltipDisabled?: ActionTooltipProps['disabled'];\n /**\n * Tooltip open delay in ms\n */\n tooltipOpenDelay?: ActionTooltipProps['openDelay'];\n /**\n * Tooltip close delay in ms\n */\n tooltipCloseDelay?: ActionTooltipProps['closeDelay'];\n /**\n * Additional CSS class for the wrapper\n */\n wrapperClassName?: string;\n}\n\n/**\n * ActionButton component combines Button with ActionTooltip\n *\n * This component wraps a Button inside an ActionTooltip, providing\n * a convenient way to add tooltips to action buttons throughout the application.\n *\n * @param props - Component props\n * @param ref - Forwarded ref to the button element\n * @returns ActionButton component\n */\nexport const ActionButton = React.forwardRef<HTMLButtonElement, ActionButtonProps>(\n (\n {\n tooltipTitle,\n tooltipPlacement,\n tooltipDisabled,\n tooltipOpenDelay,\n tooltipCloseDelay,\n wrapperClassName,\n className,\n children,\n ...buttonProps\n },\n ref,\n ) => {\n const button = (\n <Button {...buttonProps} ref={ref} className={className}>\n {children}\n </Button>\n );\n\n // If no tooltip props provided, return button without tooltip\n if (!tooltipTitle) {\n return button;\n }\n\n return (\n <ActionTooltip\n title={tooltipTitle}\n placement={tooltipPlacement}\n disabled={tooltipDisabled}\n openDelay={tooltipOpenDelay}\n closeDelay={tooltipCloseDelay}\n className={wrapperClassName}\n >\n {button}\n </ActionTooltip>\n );\n },\n);\n\nActionButton.displayName = 'ActionButton';\n"]}
@@ -1,5 +1,4 @@
1
1
  import { DOMProps, QAProps } from '@gravity-ui/uikit';
2
- import { DateLocaleConfig } from "../../../hooks/index.js";
3
2
  import "./ChatDate.css";
4
3
  export type ChatDateProps = QAProps & DOMProps & {
5
4
  /** Date value in string, Date, or number (timestamp) format */
@@ -8,10 +7,6 @@ export type ChatDateProps = QAProps & DOMProps & {
8
7
  showTime?: boolean;
9
8
  /** Custom format string (dayjs format) */
10
9
  format?: string;
11
- /** Locale for date formatting */
12
- locale?: string;
13
- /** Dayjs locale configuration for the provided locale */
14
- localeConfig?: DateLocaleConfig;
15
10
  /** Display relative dates (today, yesterday, two days ago, etc.) */
16
11
  relative?: boolean;
17
12
  };
@@ -16,13 +16,11 @@ const b = (0, cn_1.block)('chat-date');
16
16
  * @returns React component
17
17
  */
18
18
  function ChatDate(props) {
19
- const { date, showTime = false, format, locale, localeConfig, className, qa, relative = false, style, } = props;
19
+ const { date, showTime = false, format, className, qa, relative = false, style } = props;
20
20
  const isMobile = (0, uikit_1.useMobile)();
21
21
  const { formattedDate, formattedTime, fullDate, dateObject, isValid, diffDays } = (0, hooks_1.useDateFormatter)({
22
22
  date,
23
23
  format,
24
- locale,
25
- localeConfig,
26
24
  });
27
25
  if (!isValid || !dateObject) {
28
26
  return (0, i18n_1.i18n)('invalid-date');
@@ -1 +1 @@
1
- {"version":3,"file":"ChatDate.js","sourceRoot":"../../../../../src","sources":["components/atoms/ChatDate/ChatDate.tsx"],"names":[],"mappings":";;AAmCA,4BA6CC;;AAhFD,iCAA+B;AAE/B,6CAA+D;AAE/D,mDAAkE;AAClE,6CAAwC;AAExC,0CAA4B;AAE5B,0BAAyB;AAEzB,MAAM,CAAC,GAAG,IAAA,UAAK,EAAC,WAAW,CAAC,CAAC;AAkB7B;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,KAAoB;IACzC,MAAM,EACF,IAAI,EACJ,QAAQ,GAAG,KAAK,EAChB,MAAM,EACN,MAAM,EACN,YAAY,EACZ,SAAS,EACT,EAAE,EACF,QAAQ,GAAG,KAAK,EAChB,KAAK,GACR,GAAG,KAAK,CAAC;IAEV,MAAM,QAAQ,GAAG,IAAA,iBAAS,GAAE,CAAC;IAE7B,MAAM,EAAC,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAC,GACzE,IAAA,wBAAgB,EAAC;QACb,IAAI;QACJ,MAAM;QACN,MAAM;QACN,YAAY;KACf,CAAC,CAAC;IAEP,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;QAC1B,OAAO,IAAA,WAAI,EAAC,cAAc,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,CACH,iCACI,SAAS,EAAE,CAAC,CAAC,EAAC,MAAM,EAAE,QAAQ,EAAC,EAAE,SAAS,CAAC,EAC3C,QAAQ,EAAE,UAAU,CAAC,WAAW,EAAE,EAClC,KAAK,EAAE,QAAQ,aACN,EAAE,EACX,KAAK,EAAE,KAAK,YAEX,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CACxC,2CAAO,IAAA,WAAI,EAAC,KAAK,EAAE,EAAC,KAAK,EAAE,QAAQ,EAAC,CAAC,GAAQ,CAChD,CAAC,CAAC,CAAC,CACA,wBAAC,gBAAQ,eACL,2CAAO,aAAa,GAAQ,EAC5B,2CAAO,QAAQ,IAAI,aAAa,IAAI,IAAI,aAAa,EAAE,GAAQ,IACxD,CACd,GACE,CACV,CAAC;AACN,CAAC","sourcesContent":["import {Fragment} from 'react';\n\nimport {DOMProps, QAProps, useMobile} from '@gravity-ui/uikit';\n\nimport {DateLocaleConfig, useDateFormatter} from '../../../hooks';\nimport {block} from '../../../utils/cn';\n\nimport {i18n} from './i18n';\n\nimport './ChatDate.scss';\n\nconst b = block('chat-date');\n\nexport type ChatDateProps = QAProps &\n DOMProps & {\n /** Date value in string, Date, or number (timestamp) format */\n date: string | Date | number;\n /** Show time along with date */\n showTime?: boolean;\n /** Custom format string (dayjs format) */\n format?: string;\n /** Locale for date formatting */\n locale?: string;\n /** Dayjs locale configuration for the provided locale */\n localeConfig?: DateLocaleConfig;\n /** Display relative dates (today, yesterday, two days ago, etc.) */\n relative?: boolean;\n };\n\n/**\n * ChatDate component displays formatted dates with optional time\n *\n * @param props - Component props\n * @returns React component\n */\nexport function ChatDate(props: ChatDateProps) {\n const {\n date,\n showTime = false,\n format,\n locale,\n localeConfig,\n className,\n qa,\n relative = false,\n style,\n } = props;\n\n const isMobile = useMobile();\n\n const {formattedDate, formattedTime, fullDate, dateObject, isValid, diffDays} =\n useDateFormatter({\n date,\n format,\n locale,\n localeConfig,\n });\n\n if (!isValid || !dateObject) {\n return i18n('invalid-date');\n }\n\n return (\n <time\n className={b({mobile: isMobile}, className)}\n dateTime={dateObject.toISOString()}\n title={fullDate}\n data-qa={qa}\n style={style}\n >\n {relative && typeof diffDays === 'number' ? (\n <span>{i18n('ago', {count: diffDays})}</span>\n ) : (\n <Fragment>\n <span>{formattedDate}</span>\n <span>{showTime && formattedTime && ` ${formattedTime}`}</span>\n </Fragment>\n )}\n </time>\n );\n}\n"]}
1
+ {"version":3,"file":"ChatDate.js","sourceRoot":"../../../../../src","sources":["components/atoms/ChatDate/ChatDate.tsx"],"names":[],"mappings":";;AA+BA,4BAiCC;;AAhED,iCAA+B;AAE/B,6CAA+D;AAE/D,mDAAgD;AAChD,6CAAwC;AAExC,0CAA4B;AAE5B,0BAAyB;AAEzB,MAAM,CAAC,GAAG,IAAA,UAAK,EAAC,WAAW,CAAC,CAAC;AAc7B;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,KAAoB;IACzC,MAAM,EAAC,IAAI,EAAE,QAAQ,GAAG,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,GAAG,KAAK,EAAE,KAAK,EAAC,GAAG,KAAK,CAAC;IAEvF,MAAM,QAAQ,GAAG,IAAA,iBAAS,GAAE,CAAC;IAE7B,MAAM,EAAC,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAC,GACzE,IAAA,wBAAgB,EAAC;QACb,IAAI;QACJ,MAAM;KACT,CAAC,CAAC;IAEP,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;QAC1B,OAAO,IAAA,WAAI,EAAC,cAAc,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,CACH,iCACI,SAAS,EAAE,CAAC,CAAC,EAAC,MAAM,EAAE,QAAQ,EAAC,EAAE,SAAS,CAAC,EAC3C,QAAQ,EAAE,UAAU,CAAC,WAAW,EAAE,EAClC,KAAK,EAAE,QAAQ,aACN,EAAE,EACX,KAAK,EAAE,KAAK,YAEX,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CACxC,2CAAO,IAAA,WAAI,EAAC,KAAK,EAAE,EAAC,KAAK,EAAE,QAAQ,EAAC,CAAC,GAAQ,CAChD,CAAC,CAAC,CAAC,CACA,wBAAC,gBAAQ,eACL,2CAAO,aAAa,GAAQ,EAC5B,2CAAO,QAAQ,IAAI,aAAa,IAAI,IAAI,aAAa,EAAE,GAAQ,IACxD,CACd,GACE,CACV,CAAC;AACN,CAAC","sourcesContent":["import {Fragment} from 'react';\n\nimport {DOMProps, QAProps, useMobile} from '@gravity-ui/uikit';\n\nimport {useDateFormatter} from '../../../hooks';\nimport {block} from '../../../utils/cn';\n\nimport {i18n} from './i18n';\n\nimport './ChatDate.scss';\n\nconst b = block('chat-date');\n\nexport type ChatDateProps = QAProps &\n DOMProps & {\n /** Date value in string, Date, or number (timestamp) format */\n date: string | Date | number;\n /** Show time along with date */\n showTime?: boolean;\n /** Custom format string (dayjs format) */\n format?: string;\n /** Display relative dates (today, yesterday, two days ago, etc.) */\n relative?: boolean;\n };\n\n/**\n * ChatDate component displays formatted dates with optional time\n *\n * @param props - Component props\n * @returns React component\n */\nexport function ChatDate(props: ChatDateProps) {\n const {date, showTime = false, format, className, qa, relative = false, style} = props;\n\n const isMobile = useMobile();\n\n const {formattedDate, formattedTime, fullDate, dateObject, isValid, diffDays} =\n useDateFormatter({\n date,\n format,\n });\n\n if (!isValid || !dateObject) {\n return i18n('invalid-date');\n }\n\n return (\n <time\n className={b({mobile: isMobile}, className)}\n dateTime={dateObject.toISOString()}\n title={fullDate}\n data-qa={qa}\n style={style}\n >\n {relative && typeof diffDays === 'number' ? (\n <span>{i18n('ago', {count: diffDays})}</span>\n ) : (\n <Fragment>\n <span>{formattedDate}</span>\n <span>{showTime && formattedTime && ` ${formattedTime}`}</span>\n </Fragment>\n )}\n </time>\n );\n}\n"]}
@@ -2,7 +2,7 @@
2
2
  display: inline-flex;
3
3
  align-items: center;
4
4
  justify-content: center;
5
- gap: var(--g-spacing-1);
5
+ gap: 8px;
6
6
  }
7
7
  .g-aikit-context-indicator__container_orientation_horizontal {
8
8
  flex-direction: row;
@@ -1,6 +1,6 @@
1
1
  .g-aikit-prompt-input-footer {
2
2
  display: flex;
3
- align-items: center;
3
+ align-items: flex-end;
4
4
  justify-content: space-between;
5
5
  align-self: stretch;
6
6
  gap: var(--g-spacing-1);
@@ -39,7 +39,7 @@ function getNormalizedMenuItem(item, menuItemQa) {
39
39
  * @returns Header component
40
40
  */
41
41
  function Header(props) {
42
- const { title, preview, icon, baseActions, additionalActions, actionsPlacement, actionsOrder, actionSize, isMobile, actionIcons, menuItems, menuButtonTooltip, menuButtonIcon, menuButtonQa, menuItemQa, titlePosition, withIcon, showTitle = true, className, historyButtonRef, qa, actionQa, actionTooltipTexts, } = (0, useHeader_1.useHeader)(props);
42
+ const { title, preview, icon, baseActions, additionalActions, actionsPlacement, actionsOrder, actionSize, isMobile, menuItems, menuButtonTooltip, menuButtonIcon, menuButtonQa, menuItemQa, titlePosition, withIcon, showTitle = true, className, historyButtonRef, qa, actionQa, actionTooltipTexts, } = (0, useHeader_1.useHeader)(props);
43
43
  const [isMenuSheetVisible, setIsMenuSheetVisible] = (0, react_1.useState)(false);
44
44
  const menuSheetId = (0, uikit_1.useUniqId)();
45
45
  const iconSize = (0, useMobileControlSize_1.getControlIconSize)(actionSize);
@@ -48,11 +48,12 @@ function Header(props) {
48
48
  const iconElement = icon ? ((0, jsx_runtime_1.jsx)("div", { className: b('icon'), children: icon })) : ((0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: icons_1.Sparkles, size: 16 }));
49
49
  // Render base action
50
50
  const renderBaseAction = (0, react_1.useCallback)((action, ref) => {
51
- var _a, _b, _c;
52
- const actionId = action.id;
53
- const IconComponent = (_a = actionIcons === null || actionIcons === void 0 ? void 0 : actionIcons[actionId]) !== null && _a !== void 0 ? _a : (actionId === types_1.HeaderAction.Folding && action.foldingState
54
- ? FOLDING_ICONS[action.foldingState]
55
- : ACTION_ICONS[actionId]);
51
+ var _a, _b;
52
+ let IconComponent = ACTION_ICONS[action.id];
53
+ // Handle folding icon based on state
54
+ if (action.id === types_1.HeaderAction.Folding && action.foldingState) {
55
+ IconComponent = FOLDING_ICONS[action.foldingState];
56
+ }
56
57
  if (!IconComponent) {
57
58
  return null;
58
59
  }
@@ -61,7 +62,7 @@ function Header(props) {
61
62
  let tooltipOverride;
62
63
  if (action.id === types_1.HeaderAction.Folding && action.foldingState) {
63
64
  tooltipKey = `action-tooltip-folding-${action.foldingState}`;
64
- tooltipOverride = (_b = actionTooltipTexts === null || actionTooltipTexts === void 0 ? void 0 : actionTooltipTexts[types_1.HeaderAction.Folding]) === null || _b === void 0 ? void 0 : _b[action.foldingState];
65
+ tooltipOverride = (_a = actionTooltipTexts === null || actionTooltipTexts === void 0 ? void 0 : actionTooltipTexts[types_1.HeaderAction.Folding]) === null || _a === void 0 ? void 0 : _a[action.foldingState];
65
66
  }
66
67
  else {
67
68
  tooltipOverride =
@@ -69,8 +70,8 @@ function Header(props) {
69
70
  }
70
71
  // Determine ref for history button
71
72
  const buttonRef = action.id === types_1.HeaderAction.History ? ref : undefined;
72
- return ((0, jsx_runtime_1.jsx)(ActionButton_1.ActionButton, { ref: buttonRef, tooltipTitle: tooltipOverride !== null && tooltipOverride !== void 0 ? tooltipOverride : (0, i18n_1.i18n)(tooltipKey), size: actionSize, view: "flat", onClick: action.onClick, className: b('action-button'), qa: (_c = actionQa === null || actionQa === void 0 ? void 0 : actionQa[action.id]) !== null && _c !== void 0 ? _c : `header-action-${action.id}`, children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: IconComponent, size: iconSize }) }, action.id));
73
- }, [actionIcons, actionQa, actionSize, actionTooltipTexts, iconSize]);
73
+ return ((0, jsx_runtime_1.jsx)(ActionButton_1.ActionButton, { ref: buttonRef, tooltipTitle: tooltipOverride !== null && tooltipOverride !== void 0 ? tooltipOverride : (0, i18n_1.i18n)(tooltipKey), size: actionSize, view: "flat", onClick: action.onClick, className: b('action-button'), qa: (_b = actionQa === null || actionQa === void 0 ? void 0 : actionQa[action.id]) !== null && _b !== void 0 ? _b : `header-action-${action.id}`, children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: IconComponent, size: iconSize }) }, action.id));
74
+ }, [actionQa, actionSize, actionTooltipTexts, iconSize]);
74
75
  // Render additional action
75
76
  const renderAdditionalAction = (0, react_1.useCallback)((action, index) => {
76
77
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"Header.js","sourceRoot":"../../../../../src","sources":["components/organisms/Header/Header.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useCallback, useMemo, useState} from 'react';\n\nimport {\n ChevronsCollapseUpRight,\n ChevronsExpandUpRight,\n ClockArrowRotateLeft,\n Ellipsis,\n Plus,\n Sparkles,\n Xmark,\n} from '@gravity-ui/icons';\nimport {DropdownMenu, Icon, Menu, Sheet, Text, useUniqId} from '@gravity-ui/uikit';\n\nimport {Action} from 'src/types';\n\nimport {getControlIconSize} from '../../../hooks/useMobileControlSize';\nimport {isActionConfig} from '../../../utils/actionUtils';\nimport {block} from '../../../utils/cn';\nimport {ActionButton} from '../../atoms/ActionButton';\nimport {ButtonGroup} from '../../molecules/ButtonGroup';\n\nimport {i18n} from './i18n';\nimport {\n HeaderAction,\n HeaderActionGroup,\n type HeaderActionOrderItem,\n type HeaderMenuItem,\n type HeaderProps,\n} from './types';\nimport {ActionItem, useHeader} from './useHeader';\n\nimport './Header.scss';\n\nconst b = block('header');\n\n// Icons for base actions\nconst ACTION_ICONS: Record<HeaderAction, typeof Xmark> = {\n [HeaderAction.NewChat]: Plus,\n [HeaderAction.History]: ClockArrowRotateLeft,\n [HeaderAction.Folding]: ChevronsCollapseUpRight, // Default icon, will be switched based on state\n [HeaderAction.Close]: Xmark,\n};\n\n// Icons for folding states\nconst FOLDING_ICONS = {\n collapsed: ChevronsExpandUpRight,\n opened: ChevronsCollapseUpRight,\n};\n\ntype NormalizedMenuItem = HeaderMenuItem & {qa: string};\n\nfunction getNormalizedMenuItem(\n item: HeaderMenuItem,\n menuItemQa: HeaderProps['menuItemQa'],\n): NormalizedMenuItem {\n return {...item, qa: menuItemQa?.[item.id] ?? `header-menu-item-${item.id}`};\n}\n\n/**\n * Header component for displaying chat header with navigation and actions\n *\n * @param props - Component props\n * @returns Header component\n */\nexport function Header(props: HeaderProps) {\n const {\n title,\n preview,\n icon,\n baseActions,\n additionalActions,\n actionsPlacement,\n actionsOrder,\n actionSize,\n isMobile,\n actionIcons,\n menuItems,\n menuButtonTooltip,\n menuButtonIcon,\n menuButtonQa,\n menuItemQa,\n titlePosition,\n withIcon,\n showTitle = true,\n className,\n historyButtonRef,\n qa,\n actionQa,\n actionTooltipTexts,\n } = useHeader(props);\n\n const [isMenuSheetVisible, setIsMenuSheetVisible] = useState(false);\n const menuSheetId = useUniqId();\n\n const iconSize = getControlIconSize(actionSize);\n\n // Determine class for title positioning\n const titlePositionClass = b('title-container', {position: titlePosition});\n\n const iconElement = icon ? (\n <div className={b('icon')}>{icon}</div>\n ) : (\n <Icon data={Sparkles} size={16} />\n );\n\n // Render base action\n const renderBaseAction = useCallback(\n (action: ActionItem, ref?: React.RefObject<HTMLElement>) => {\n const actionId = action.id as HeaderAction;\n const IconComponent =\n actionIcons?.[actionId] ??\n (actionId === HeaderAction.Folding && action.foldingState\n ? FOLDING_ICONS[action.foldingState]\n : ACTION_ICONS[actionId]);\n\n if (!IconComponent) {\n return null;\n }\n\n // Get tooltip text\n let tooltipKey = `action-tooltip-${action.id}`;\n let tooltipOverride: string | undefined;\n if (action.id === HeaderAction.Folding && action.foldingState) {\n tooltipKey = `action-tooltip-folding-${action.foldingState}`;\n tooltipOverride = actionTooltipTexts?.[HeaderAction.Folding]?.[action.foldingState];\n } else {\n tooltipOverride =\n actionTooltipTexts?.[action.id as Exclude<HeaderAction, HeaderAction.Folding>];\n }\n\n // Determine ref for history button\n const buttonRef = action.id === HeaderAction.History ? ref : undefined;\n\n return (\n <ActionButton\n key={action.id}\n ref={buttonRef as React.Ref<HTMLButtonElement>}\n tooltipTitle={tooltipOverride ?? i18n(tooltipKey as Parameters<typeof i18n>[0])}\n size={actionSize}\n view=\"flat\"\n onClick={action.onClick}\n className={b('action-button')}\n qa={actionQa?.[action.id as HeaderAction] ?? `header-action-${action.id}`}\n >\n <Icon data={IconComponent} size={iconSize} />\n </ActionButton>\n );\n },\n [actionIcons, actionQa, actionSize, actionTooltipTexts, iconSize],\n );\n\n // Render additional action\n const renderAdditionalAction = useCallback(\n (action: Action, index: number) => {\n const id = `additional-${index}`;\n\n if (!isActionConfig(action)) {\n return <React.Fragment key={id}>{action}</React.Fragment>;\n }\n\n return (\n <ActionButton\n key={`${index}`}\n {...action}\n view={action.view || 'flat'}\n size={action.size ?? actionSize}\n >\n {action.icon || action.label}\n </ActionButton>\n );\n },\n [actionSize],\n );\n\n const normalizedMenuItems = useMemo(\n () => menuItems.map((item) => getNormalizedMenuItem(item, menuItemQa)),\n [menuItems, menuItemQa],\n );\n\n const dropdownMenuItems = useMemo(\n () =>\n normalizedMenuItems.map((item) => ({\n text: item.label,\n action: item.onClick,\n disabled: item.disabled,\n qa: item.qa,\n ...(item.icon ? {iconStart: item.icon} : {}),\n })),\n [normalizedMenuItems],\n );\n\n const headerMenu = useMemo(() => {\n if (normalizedMenuItems.length === 0) {\n return null;\n }\n\n const switcherContent = menuButtonIcon ?? <Icon data={Ellipsis} size={iconSize} />;\n const switcherTooltip = menuButtonTooltip ?? i18n('action-tooltip-menu');\n const switcherQa = menuButtonQa ?? 'header-menu-button';\n\n if (isMobile) {\n return (\n <React.Fragment>\n <ActionButton\n tooltipTitle={switcherTooltip}\n size={actionSize}\n view=\"flat\"\n className={b('action-button')}\n qa={switcherQa}\n onClick={() => setIsMenuSheetVisible(true)}\n >\n {switcherContent}\n </ActionButton>\n <Sheet\n id={menuSheetId}\n title={i18n('menu-sheet-title')}\n visible={isMenuSheetVisible}\n onClose={() => setIsMenuSheetVisible(false)}\n contentClassName={b('menu-sheet-content')}\n qa=\"header-menu-sheet-container\"\n >\n <Menu size=\"xl\" qa=\"header-menu-sheet\">\n {normalizedMenuItems.map((item) => (\n <Menu.Item\n key={item.id}\n disabled={item.disabled}\n iconStart={item.icon}\n qa={item.qa}\n onClick={() => {\n setIsMenuSheetVisible(false);\n item.onClick();\n }}\n >\n {item.label}\n </Menu.Item>\n ))}\n </Menu>\n </Sheet>\n </React.Fragment>\n );\n }\n\n return (\n <DropdownMenu\n items={dropdownMenuItems}\n renderSwitcher={(switcherProps) => (\n <ActionButton\n {...switcherProps}\n tooltipTitle={switcherTooltip}\n size={actionSize}\n view=\"flat\"\n className={b('action-button')}\n qa={switcherQa}\n >\n {switcherContent}\n </ActionButton>\n )}\n />\n );\n }, [\n actionSize,\n iconSize,\n isMobile,\n isMenuSheetVisible,\n menuSheetId,\n dropdownMenuItems,\n normalizedMenuItems,\n menuButtonIcon,\n menuButtonQa,\n menuButtonTooltip,\n ]);\n\n const [leftBaseActions, rightBaseActions] = useMemo(() => {\n const left: ActionItem[] = [];\n const right: ActionItem[] = [];\n baseActions.forEach((action) => {\n (actionsPlacement.base?.[action.id as HeaderAction] === 'left' ? left : right).push(\n action,\n );\n });\n return [left, right];\n }, [actionsPlacement.base, baseActions]);\n\n const renderActions = (side: 'left' | 'right') => {\n const sideAdditionalActions =\n (actionsPlacement.additional ?? 'right') === side ? additionalActions : [];\n const sideMenu = (actionsPlacement.menu ?? 'right') === side ? headerMenu : null;\n const sideBaseActions = side === 'left' ? leftBaseActions : rightBaseActions;\n if (sideAdditionalActions.length === 0 && !sideMenu && sideBaseActions.length === 0) {\n return null;\n }\n const legacyOrder: HeaderActionOrderItem[] = [\n ...(sideAdditionalActions.length > 0 ? [HeaderActionGroup.Additional] : []),\n ...(sideMenu ? [HeaderActionGroup.Menu] : []),\n ...sideBaseActions.map((action) => action.id as HeaderAction),\n ];\n const requestedOrder = actionsOrder[side] ?? [];\n const available = new Set(legacyOrder);\n const ordered = [...new Set([...requestedOrder, ...legacyOrder])].filter((item) =>\n available.has(item),\n );\n\n const renderOrderedAction = (item: HeaderActionOrderItem) => {\n if (item === HeaderActionGroup.Additional) {\n return sideAdditionalActions.map((action, index) =>\n renderAdditionalAction(action, index),\n );\n }\n if (item === HeaderActionGroup.Menu) {\n return <React.Fragment key=\"menu\">{sideMenu}</React.Fragment>;\n }\n const action = sideBaseActions.find((candidate) => candidate.id === item);\n return action ? renderBaseAction(action, historyButtonRef) : null;\n };\n\n return <ButtonGroup>{ordered.map(renderOrderedAction)}</ButtonGroup>;\n };\n\n const leftActions = renderActions('left');\n const rightActions = renderActions('right');\n\n return (\n <div className={b('', className)} data-qa={qa}>\n {(withIcon || leftActions) && (\n <div className={b('left')}>\n {withIcon && iconElement}\n {leftActions}\n </div>\n )}\n\n {/* Center part: title with preview */}\n {showTitle && (\n <div className={titlePositionClass}>\n {title && (\n <Text title={title} as=\"div\" variant=\"subheader-2\" className={b('title')}>\n {title}\n </Text>\n )}\n {preview && <div className={b('preview')}>{preview}</div>}\n </div>\n )}\n\n {rightActions}\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"Header.js","sourceRoot":"../../../../../src","sources":["components/organisms/Header/Header.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useCallback, useMemo, useState} from 'react';\n\nimport {\n ChevronsCollapseUpRight,\n ChevronsExpandUpRight,\n ClockArrowRotateLeft,\n Ellipsis,\n Plus,\n Sparkles,\n Xmark,\n} from '@gravity-ui/icons';\nimport {DropdownMenu, Icon, Menu, Sheet, Text, useUniqId} from '@gravity-ui/uikit';\n\nimport {Action} from 'src/types';\n\nimport {getControlIconSize} from '../../../hooks/useMobileControlSize';\nimport {isActionConfig} from '../../../utils/actionUtils';\nimport {block} from '../../../utils/cn';\nimport {ActionButton} from '../../atoms/ActionButton';\nimport {ButtonGroup} from '../../molecules/ButtonGroup';\n\nimport {i18n} from './i18n';\nimport {\n HeaderAction,\n HeaderActionGroup,\n type HeaderActionOrderItem,\n type HeaderMenuItem,\n type HeaderProps,\n} from './types';\nimport {ActionItem, useHeader} from './useHeader';\n\nimport './Header.scss';\n\nconst b = block('header');\n\n// Icons for base actions\nconst ACTION_ICONS: Record<HeaderAction, typeof Xmark> = {\n [HeaderAction.NewChat]: Plus,\n [HeaderAction.History]: ClockArrowRotateLeft,\n [HeaderAction.Folding]: ChevronsCollapseUpRight, // Default icon, will be switched based on state\n [HeaderAction.Close]: Xmark,\n};\n\n// Icons for folding states\nconst FOLDING_ICONS = {\n collapsed: ChevronsExpandUpRight,\n opened: ChevronsCollapseUpRight,\n};\n\ntype NormalizedMenuItem = HeaderMenuItem & {qa: string};\n\nfunction getNormalizedMenuItem(\n item: HeaderMenuItem,\n menuItemQa: HeaderProps['menuItemQa'],\n): NormalizedMenuItem {\n return {...item, qa: menuItemQa?.[item.id] ?? `header-menu-item-${item.id}`};\n}\n\n/**\n * Header component for displaying chat header with navigation and actions\n *\n * @param props - Component props\n * @returns Header component\n */\nexport function Header(props: HeaderProps) {\n const {\n title,\n preview,\n icon,\n baseActions,\n additionalActions,\n actionsPlacement,\n actionsOrder,\n actionSize,\n isMobile,\n menuItems,\n menuButtonTooltip,\n menuButtonIcon,\n menuButtonQa,\n menuItemQa,\n titlePosition,\n withIcon,\n showTitle = true,\n className,\n historyButtonRef,\n qa,\n actionQa,\n actionTooltipTexts,\n } = useHeader(props);\n\n const [isMenuSheetVisible, setIsMenuSheetVisible] = useState(false);\n const menuSheetId = useUniqId();\n\n const iconSize = getControlIconSize(actionSize);\n\n // Determine class for title positioning\n const titlePositionClass = b('title-container', {position: titlePosition});\n\n const iconElement = icon ? (\n <div className={b('icon')}>{icon}</div>\n ) : (\n <Icon data={Sparkles} size={16} />\n );\n\n // Render base action\n const renderBaseAction = useCallback(\n (action: ActionItem, ref?: React.RefObject<HTMLElement>) => {\n let IconComponent = ACTION_ICONS[action.id as HeaderAction];\n\n // Handle folding icon based on state\n if (action.id === HeaderAction.Folding && action.foldingState) {\n IconComponent = FOLDING_ICONS[action.foldingState];\n }\n\n if (!IconComponent) {\n return null;\n }\n\n // Get tooltip text\n let tooltipKey = `action-tooltip-${action.id}`;\n let tooltipOverride: string | undefined;\n if (action.id === HeaderAction.Folding && action.foldingState) {\n tooltipKey = `action-tooltip-folding-${action.foldingState}`;\n tooltipOverride = actionTooltipTexts?.[HeaderAction.Folding]?.[action.foldingState];\n } else {\n tooltipOverride =\n actionTooltipTexts?.[action.id as Exclude<HeaderAction, HeaderAction.Folding>];\n }\n\n // Determine ref for history button\n const buttonRef = action.id === HeaderAction.History ? ref : undefined;\n\n return (\n <ActionButton\n key={action.id}\n ref={buttonRef as React.Ref<HTMLButtonElement>}\n tooltipTitle={tooltipOverride ?? i18n(tooltipKey as Parameters<typeof i18n>[0])}\n size={actionSize}\n view=\"flat\"\n onClick={action.onClick}\n className={b('action-button')}\n qa={actionQa?.[action.id as HeaderAction] ?? `header-action-${action.id}`}\n >\n <Icon data={IconComponent} size={iconSize} />\n </ActionButton>\n );\n },\n [actionQa, actionSize, actionTooltipTexts, iconSize],\n );\n\n // Render additional action\n const renderAdditionalAction = useCallback(\n (action: Action, index: number) => {\n const id = `additional-${index}`;\n\n if (!isActionConfig(action)) {\n return <React.Fragment key={id}>{action}</React.Fragment>;\n }\n\n return (\n <ActionButton\n key={`${index}`}\n {...action}\n view={action.view || 'flat'}\n size={action.size ?? actionSize}\n >\n {action.icon || action.label}\n </ActionButton>\n );\n },\n [actionSize],\n );\n\n const normalizedMenuItems = useMemo(\n () => menuItems.map((item) => getNormalizedMenuItem(item, menuItemQa)),\n [menuItems, menuItemQa],\n );\n\n const dropdownMenuItems = useMemo(\n () =>\n normalizedMenuItems.map((item) => ({\n text: item.label,\n action: item.onClick,\n disabled: item.disabled,\n qa: item.qa,\n ...(item.icon ? {iconStart: item.icon} : {}),\n })),\n [normalizedMenuItems],\n );\n\n const headerMenu = useMemo(() => {\n if (normalizedMenuItems.length === 0) {\n return null;\n }\n\n const switcherContent = menuButtonIcon ?? <Icon data={Ellipsis} size={iconSize} />;\n const switcherTooltip = menuButtonTooltip ?? i18n('action-tooltip-menu');\n const switcherQa = menuButtonQa ?? 'header-menu-button';\n\n if (isMobile) {\n return (\n <React.Fragment>\n <ActionButton\n tooltipTitle={switcherTooltip}\n size={actionSize}\n view=\"flat\"\n className={b('action-button')}\n qa={switcherQa}\n onClick={() => setIsMenuSheetVisible(true)}\n >\n {switcherContent}\n </ActionButton>\n <Sheet\n id={menuSheetId}\n title={i18n('menu-sheet-title')}\n visible={isMenuSheetVisible}\n onClose={() => setIsMenuSheetVisible(false)}\n contentClassName={b('menu-sheet-content')}\n qa=\"header-menu-sheet-container\"\n >\n <Menu size=\"xl\" qa=\"header-menu-sheet\">\n {normalizedMenuItems.map((item) => (\n <Menu.Item\n key={item.id}\n disabled={item.disabled}\n iconStart={item.icon}\n qa={item.qa}\n onClick={() => {\n setIsMenuSheetVisible(false);\n item.onClick();\n }}\n >\n {item.label}\n </Menu.Item>\n ))}\n </Menu>\n </Sheet>\n </React.Fragment>\n );\n }\n\n return (\n <DropdownMenu\n items={dropdownMenuItems}\n renderSwitcher={(switcherProps) => (\n <ActionButton\n {...switcherProps}\n tooltipTitle={switcherTooltip}\n size={actionSize}\n view=\"flat\"\n className={b('action-button')}\n qa={switcherQa}\n >\n {switcherContent}\n </ActionButton>\n )}\n />\n );\n }, [\n actionSize,\n iconSize,\n isMobile,\n isMenuSheetVisible,\n menuSheetId,\n dropdownMenuItems,\n normalizedMenuItems,\n menuButtonIcon,\n menuButtonQa,\n menuButtonTooltip,\n ]);\n\n const [leftBaseActions, rightBaseActions] = useMemo(() => {\n const left: ActionItem[] = [];\n const right: ActionItem[] = [];\n baseActions.forEach((action) => {\n (actionsPlacement.base?.[action.id as HeaderAction] === 'left' ? left : right).push(\n action,\n );\n });\n return [left, right];\n }, [actionsPlacement.base, baseActions]);\n\n const renderActions = (side: 'left' | 'right') => {\n const sideAdditionalActions =\n (actionsPlacement.additional ?? 'right') === side ? additionalActions : [];\n const sideMenu = (actionsPlacement.menu ?? 'right') === side ? headerMenu : null;\n const sideBaseActions = side === 'left' ? leftBaseActions : rightBaseActions;\n if (sideAdditionalActions.length === 0 && !sideMenu && sideBaseActions.length === 0) {\n return null;\n }\n const legacyOrder: HeaderActionOrderItem[] = [\n ...(sideAdditionalActions.length > 0 ? [HeaderActionGroup.Additional] : []),\n ...(sideMenu ? [HeaderActionGroup.Menu] : []),\n ...sideBaseActions.map((action) => action.id as HeaderAction),\n ];\n const requestedOrder = actionsOrder[side] ?? [];\n const available = new Set(legacyOrder);\n const ordered = [...new Set([...requestedOrder, ...legacyOrder])].filter((item) =>\n available.has(item),\n );\n\n const renderOrderedAction = (item: HeaderActionOrderItem) => {\n if (item === HeaderActionGroup.Additional) {\n return sideAdditionalActions.map((action, index) =>\n renderAdditionalAction(action, index),\n );\n }\n if (item === HeaderActionGroup.Menu) {\n return <React.Fragment key=\"menu\">{sideMenu}</React.Fragment>;\n }\n const action = sideBaseActions.find((candidate) => candidate.id === item);\n return action ? renderBaseAction(action, historyButtonRef) : null;\n };\n\n return <ButtonGroup>{ordered.map(renderOrderedAction)}</ButtonGroup>;\n };\n\n const leftActions = renderActions('left');\n const rightActions = renderActions('right');\n\n return (\n <div className={b('', className)} data-qa={qa}>\n {(withIcon || leftActions) && (\n <div className={b('left')}>\n {withIcon && iconElement}\n {leftActions}\n </div>\n )}\n\n {/* Center part: title with preview */}\n {showTitle && (\n <div className={titlePositionClass}>\n {title && (\n <Text title={title} as=\"div\" variant=\"subheader-2\" className={b('title')}>\n {title}\n </Text>\n )}\n {preview && <div className={b('preview')}>{preview}</div>}\n </div>\n )}\n\n {rightActions}\n </div>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { ButtonButtonProps, IconData } from '@gravity-ui/uikit';
1
+ import type { ButtonButtonProps } from '@gravity-ui/uikit';
2
2
  import type { Action } from "../../../types/common.js";
3
3
  export type HeaderMenuItem = {
4
4
  id: string;
@@ -49,8 +49,6 @@ export type HeaderProps = {
49
49
  actionsOrder?: HeaderActionsOrder;
50
50
  /** Default size for built-in, menu, and configured additional action buttons. */
51
51
  actionSize?: ButtonButtonProps['size'];
52
- /** Custom icons for built-in actions. Unspecified actions keep their default icons. */
53
- actionIcons?: Partial<Record<HeaderAction, IconData>>;
54
52
  /**
55
53
  * Menu items for the "..." dropdown. Labels and handlers are provided by the consumer.
56
54
  * The menu button is rendered only when the array is non-empty.
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"../../../../../src","sources":["components/organisms/Header/types.ts"],"names":[],"mappings":";;;AAaA,IAAY,YAKX;AALD,WAAY,YAAY;IACpB,mCAAmB,CAAA;IACnB,mCAAmB,CAAA;IACnB,mCAAmB,CAAA;IACnB,+BAAe,CAAA;AACnB,CAAC,EALW,YAAY,4BAAZ,YAAY,QAKvB;AAED,mFAAmF;AACnF,IAAY,iBAGX;AAHD,WAAY,iBAAiB;IACzB,kCAAa,CAAA;IACb,8CAAyB,CAAA;AAC7B,CAAC,EAHW,iBAAiB,iCAAjB,iBAAiB,QAG5B","sourcesContent":["import type {ButtonButtonProps, IconData} from '@gravity-ui/uikit';\n\nimport type {Action} from '../../../types/common';\n\nexport type HeaderMenuItem = {\n id: string;\n label: string;\n onClick: () => void;\n disabled?: boolean;\n /** Optional leading icon (rendered only when provided) */\n icon?: React.ReactNode;\n};\n\nexport enum HeaderAction {\n NewChat = 'newChat',\n History = 'history',\n Folding = 'folding',\n Close = 'close',\n}\n\n/** Composite and service action groups that can participate in header ordering. */\nexport enum HeaderActionGroup {\n Menu = 'menu',\n Additional = 'additional',\n}\n\nexport type HeaderActionSide = 'left' | 'right';\n\nexport type HeaderActionsPlacement = {\n /** Side for individual built-in actions. Unspecified actions stay on the right. */\n base?: Partial<Record<HeaderAction, HeaderActionSide>>;\n /** Side for the menu button. */\n menu?: HeaderActionSide;\n /** Side for the whole additional actions group. */\n additional?: HeaderActionSide;\n};\n\nexport type HeaderActionOrderItem = HeaderAction | HeaderActionGroup;\n\nexport type HeaderActionsOrder = Partial<\n Record<HeaderActionSide, readonly HeaderActionOrderItem[]>\n>;\n\nexport type HeaderActionTooltipTexts = Partial<\n Record<Exclude<HeaderAction, HeaderAction.Folding>, string>\n> & {\n /** Tooltip texts for {@link HeaderAction.Folding}. */\n [HeaderAction.Folding]?: Partial<Record<'collapsed' | 'opened', string>>;\n};\n\nexport type HeaderProps = {\n // Content\n icon?: React.ReactNode;\n title?: string;\n preview?: React.ReactNode;\n\n // Actions\n baseActions?: HeaderAction[];\n handleNewChat?: () => void;\n handleHistoryToggle?: () => void;\n handleFolding?: (value: 'collapsed' | 'opened') => void;\n handleClose?: () => void;\n additionalActions?: Action[];\n actionsPlacement?: HeaderActionsPlacement;\n /** Order of action groups on each side. Unlisted available actions keep their legacy order. */\n actionsOrder?: HeaderActionsOrder;\n /** Default size for built-in, menu, and configured additional action buttons. */\n actionSize?: ButtonButtonProps['size'];\n /** Custom icons for built-in actions. Unspecified actions keep their default icons. */\n actionIcons?: Partial<Record<HeaderAction, IconData>>;\n\n /**\n * Menu items for the \"...\" dropdown. Labels and handlers are provided by the consumer.\n * The menu button is rendered only when the array is non-empty.\n */\n menuItems?: HeaderMenuItem[];\n /** Tooltip for the menu button (default: built-in i18n) */\n menuButtonTooltip?: string;\n /** Custom menu button icon (default: horizontal Ellipsis) */\n menuButtonIcon?: React.ReactNode;\n /** data-qa for the menu button (default: `header-menu-button`) */\n menuButtonQa?: string;\n /** data-qa overrides per menu item id (default: `header-menu-item-${id}`) */\n menuItemQa?: Partial<Record<string, string>>;\n\n /**\n * Notification callback fired by ChatContainer when the history popup is toggled\n * via the Header action button. Receives the next open state (the value the chat\n * will be in after the toggle).\n */\n onHistoryToggle?: (open: boolean) => void;\n\n // Refs\n historyButtonRef?: React.RefObject<HTMLElement>;\n\n // Folding state\n foldingState?: 'collapsed' | 'opened';\n\n // Display settings\n titlePosition?: 'left' | 'center'; // default: left\n withIcon?: boolean; // default: true\n showTitle?: boolean; // default: true - controls visibility of title and preview\n\n className?: string;\n\n /** QA/test identifier on header root */\n qa?: string;\n /** Per base action `data-qa` (defaults to `header-action-${id}`) */\n actionQa?: Partial<Record<HeaderAction, string>>;\n /**\n * Override tooltip texts per base action. When a value is undefined, the built-in\n * localized string is used (e.g. `i18n('action-tooltip-newChat')`).\n */\n actionTooltipTexts?: HeaderActionTooltipTexts;\n};\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"../../../../../src","sources":["components/organisms/Header/types.ts"],"names":[],"mappings":";;;AAaA,IAAY,YAKX;AALD,WAAY,YAAY;IACpB,mCAAmB,CAAA;IACnB,mCAAmB,CAAA;IACnB,mCAAmB,CAAA;IACnB,+BAAe,CAAA;AACnB,CAAC,EALW,YAAY,4BAAZ,YAAY,QAKvB;AAED,mFAAmF;AACnF,IAAY,iBAGX;AAHD,WAAY,iBAAiB;IACzB,kCAAa,CAAA;IACb,8CAAyB,CAAA;AAC7B,CAAC,EAHW,iBAAiB,iCAAjB,iBAAiB,QAG5B","sourcesContent":["import type {ButtonButtonProps} from '@gravity-ui/uikit';\n\nimport type {Action} from '../../../types/common';\n\nexport type HeaderMenuItem = {\n id: string;\n label: string;\n onClick: () => void;\n disabled?: boolean;\n /** Optional leading icon (rendered only when provided) */\n icon?: React.ReactNode;\n};\n\nexport enum HeaderAction {\n NewChat = 'newChat',\n History = 'history',\n Folding = 'folding',\n Close = 'close',\n}\n\n/** Composite and service action groups that can participate in header ordering. */\nexport enum HeaderActionGroup {\n Menu = 'menu',\n Additional = 'additional',\n}\n\nexport type HeaderActionSide = 'left' | 'right';\n\nexport type HeaderActionsPlacement = {\n /** Side for individual built-in actions. Unspecified actions stay on the right. */\n base?: Partial<Record<HeaderAction, HeaderActionSide>>;\n /** Side for the menu button. */\n menu?: HeaderActionSide;\n /** Side for the whole additional actions group. */\n additional?: HeaderActionSide;\n};\n\nexport type HeaderActionOrderItem = HeaderAction | HeaderActionGroup;\n\nexport type HeaderActionsOrder = Partial<\n Record<HeaderActionSide, readonly HeaderActionOrderItem[]>\n>;\n\nexport type HeaderActionTooltipTexts = Partial<\n Record<Exclude<HeaderAction, HeaderAction.Folding>, string>\n> & {\n /** Tooltip texts for {@link HeaderAction.Folding}. */\n [HeaderAction.Folding]?: Partial<Record<'collapsed' | 'opened', string>>;\n};\n\nexport type HeaderProps = {\n // Content\n icon?: React.ReactNode;\n title?: string;\n preview?: React.ReactNode;\n\n // Actions\n baseActions?: HeaderAction[];\n handleNewChat?: () => void;\n handleHistoryToggle?: () => void;\n handleFolding?: (value: 'collapsed' | 'opened') => void;\n handleClose?: () => void;\n additionalActions?: Action[];\n actionsPlacement?: HeaderActionsPlacement;\n /** Order of action groups on each side. Unlisted available actions keep their legacy order. */\n actionsOrder?: HeaderActionsOrder;\n /** Default size for built-in, menu, and configured additional action buttons. */\n actionSize?: ButtonButtonProps['size'];\n\n /**\n * Menu items for the \"...\" dropdown. Labels and handlers are provided by the consumer.\n * The menu button is rendered only when the array is non-empty.\n */\n menuItems?: HeaderMenuItem[];\n /** Tooltip for the menu button (default: built-in i18n) */\n menuButtonTooltip?: string;\n /** Custom menu button icon (default: horizontal Ellipsis) */\n menuButtonIcon?: React.ReactNode;\n /** data-qa for the menu button (default: `header-menu-button`) */\n menuButtonQa?: string;\n /** data-qa overrides per menu item id (default: `header-menu-item-${id}`) */\n menuItemQa?: Partial<Record<string, string>>;\n\n /**\n * Notification callback fired by ChatContainer when the history popup is toggled\n * via the Header action button. Receives the next open state (the value the chat\n * will be in after the toggle).\n */\n onHistoryToggle?: (open: boolean) => void;\n\n // Refs\n historyButtonRef?: React.RefObject<HTMLElement>;\n\n // Folding state\n foldingState?: 'collapsed' | 'opened';\n\n // Display settings\n titlePosition?: 'left' | 'center'; // default: left\n withIcon?: boolean; // default: true\n showTitle?: boolean; // default: true - controls visibility of title and preview\n\n className?: string;\n\n /** QA/test identifier on header root */\n qa?: string;\n /** Per base action `data-qa` (defaults to `header-action-${id}`) */\n actionQa?: Partial<Record<HeaderAction, string>>;\n /**\n * Override tooltip texts per base action. When a value is undefined, the built-in\n * localized string is used (e.g. `i18n('action-tooltip-newChat')`).\n */\n actionTooltipTexts?: HeaderActionTooltipTexts;\n};\n"]}
@@ -17,7 +17,6 @@ export declare function useHeader(props: HeaderProps): {
17
17
  actionsOrder: NonNullable<HeaderProps['actionsOrder']>;
18
18
  actionSize: NonNullable<HeaderProps['actionSize']>;
19
19
  isMobile: boolean;
20
- actionIcons?: HeaderProps['actionIcons'];
21
20
  titlePosition: 'left' | 'center';
22
21
  withIcon: boolean;
23
22
  showTitle: boolean;
@@ -5,7 +5,7 @@ const react_1 = require("react");
5
5
  const uikit_1 = require("@gravity-ui/uikit");
6
6
  const types_1 = require("./types.js");
7
7
  function useHeader(props) {
8
- const { icon, title, preview, baseActions = [], handleNewChat, handleHistoryToggle, handleClose, handleFolding, foldingState = 'opened', additionalActions = [], actionsPlacement = {}, actionsOrder = {}, actionSize: actionSizeProp, actionIcons, menuItems = [], menuButtonTooltip, menuButtonIcon, menuButtonQa, menuItemQa, titlePosition = 'left', withIcon = true, showTitle = true, className, historyButtonRef, qa, actionQa, actionTooltipTexts, } = props;
8
+ const { icon, title, preview, baseActions = [], handleNewChat, handleHistoryToggle, handleClose, handleFolding, foldingState = 'opened', additionalActions = [], actionsPlacement = {}, actionsOrder = {}, actionSize: actionSizeProp, menuItems = [], menuButtonTooltip, menuButtonIcon, menuButtonQa, menuItemQa, titlePosition = 'left', withIcon = true, showTitle = true, className, historyButtonRef, qa, actionQa, actionTooltipTexts, } = props;
9
9
  const isMobile = (0, uikit_1.useMobile)();
10
10
  const actionSize = actionSizeProp !== null && actionSizeProp !== void 0 ? actionSizeProp : (isMobile ? 'xl' : 'm');
11
11
  // Build base actions
@@ -52,7 +52,6 @@ function useHeader(props) {
52
52
  actionsOrder,
53
53
  actionSize,
54
54
  isMobile,
55
- actionIcons,
56
55
  titlePosition,
57
56
  withIcon,
58
57
  showTitle,
@@ -1 +1 @@
1
- {"version":3,"file":"useHeader.js","sourceRoot":"../../../../../src","sources":["components/organisms/Header/useHeader.ts"],"names":[],"mappings":";;AAeA,8BA0HC;AAzID,iCAAqC;AAErC,6CAA4C;AAI5C,sCAA4E;AAS5E,SAAgB,SAAS,CAAC,KAAkB;IAyBxC,MAAM,EACF,IAAI,EACJ,KAAK,EACL,OAAO,EACP,WAAW,GAAG,EAAE,EAChB,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,YAAY,GAAG,QAAQ,EACvB,iBAAiB,GAAG,EAAE,EACtB,gBAAgB,GAAG,EAAE,EACrB,YAAY,GAAG,EAAE,EACjB,UAAU,EAAE,cAAc,EAC1B,WAAW,EACX,SAAS,GAAG,EAAE,EACd,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,aAAa,GAAG,MAAM,EACtB,QAAQ,GAAG,IAAI,EACf,SAAS,GAAG,IAAI,EAChB,SAAS,EACT,gBAAgB,EAChB,EAAE,EACF,QAAQ,EACR,kBAAkB,GACrB,GAAG,KAAK,CAAC;IAEV,MAAM,QAAQ,GAAG,IAAA,iBAAS,GAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAE7D,qBAAqB;IACrB,MAAM,eAAe,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QACjC,MAAM,OAAO,GAAiB,EAAE,CAAC;QAEjC,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAC3B,IAAI,MAAM,KAAK,oBAAY,CAAC,OAAO,EAAE,CAAC;gBAClC,IAAI,aAAa,EAAE,CAAC;oBAChB,OAAO,CAAC,IAAI,CAAC;wBACT,EAAE,EAAE,MAAM;wBACV,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,GAAG,EAAE;4BACV,MAAM,QAAQ,GAAG,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;4BACpE,aAAa,CAAC,QAAQ,CAAC,CAAC;wBAC5B,CAAC;wBACD,YAAY;qBACf,CAAC,CAAC;gBACP,CAAC;gBACD,OAAO;YACX,CAAC;YAED,MAAM,SAAS,GAA8C;gBACzD,CAAC,oBAAY,CAAC,OAAO,CAAC,EAAE,aAAa;gBACrC,CAAC,oBAAY,CAAC,OAAO,CAAC,EAAE,mBAAmB;gBAC3C,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,WAAW;aACpC,CAAC;YAEF,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC;oBACT,EAAE,EAAE,MAAM;oBACV,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,OAAO;iBACnB,CAAC,CAAC;YACP,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;IACnB,CAAC,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;IAEhG,OAAO;QACH,KAAK;QACL,OAAO;QACP,IAAI;QACJ,WAAW,EAAE,eAAe;QAC5B,iBAAiB;QACjB,gBAAgB;QAChB,YAAY;QACZ,UAAU;QACV,QAAQ;QACR,WAAW;QACX,aAAa;QACb,QAAQ;QACR,SAAS;QACT,SAAS;QACT,gBAAgB;QAChB,EAAE;QACF,QAAQ;QACR,kBAAkB;QAClB,SAAS;QACT,iBAAiB;QACjB,cAAc;QACd,YAAY;QACZ,UAAU;KACb,CAAC;AACN,CAAC","sourcesContent":["import React, {useMemo} from 'react';\n\nimport {useMobile} from '@gravity-ui/uikit';\n\nimport type {Action} from '../../../types/common';\n\nimport {HeaderAction, type HeaderMenuItem, type HeaderProps} from './types';\n\nexport type ActionItem = {\n id: string;\n type: 'base' | 'additional';\n onClick?: () => void;\n foldingState?: 'collapsed' | 'opened';\n};\n\nexport function useHeader(props: HeaderProps): {\n title: string | undefined;\n preview: React.ReactNode | undefined;\n icon: React.ReactNode | undefined;\n baseActions: ActionItem[];\n additionalActions: Action[];\n actionsPlacement: NonNullable<HeaderProps['actionsPlacement']>;\n actionsOrder: NonNullable<HeaderProps['actionsOrder']>;\n actionSize: NonNullable<HeaderProps['actionSize']>;\n isMobile: boolean;\n actionIcons?: HeaderProps['actionIcons'];\n titlePosition: 'left' | 'center';\n withIcon: boolean;\n showTitle: boolean;\n className?: string;\n historyButtonRef?: React.RefObject<HTMLElement>;\n qa?: string;\n actionQa?: HeaderProps['actionQa'];\n actionTooltipTexts?: HeaderProps['actionTooltipTexts'];\n menuItems: HeaderMenuItem[];\n menuButtonTooltip?: string;\n menuButtonIcon?: React.ReactNode;\n menuButtonQa?: string;\n menuItemQa?: HeaderProps['menuItemQa'];\n} {\n const {\n icon,\n title,\n preview,\n baseActions = [],\n handleNewChat,\n handleHistoryToggle,\n handleClose,\n handleFolding,\n foldingState = 'opened',\n additionalActions = [],\n actionsPlacement = {},\n actionsOrder = {},\n actionSize: actionSizeProp,\n actionIcons,\n menuItems = [],\n menuButtonTooltip,\n menuButtonIcon,\n menuButtonQa,\n menuItemQa,\n titlePosition = 'left',\n withIcon = true,\n showTitle = true,\n className,\n historyButtonRef,\n qa,\n actionQa,\n actionTooltipTexts,\n } = props;\n\n const isMobile = useMobile();\n const actionSize = actionSizeProp ?? (isMobile ? 'xl' : 'm');\n\n // Build base actions\n const baseActionsList = useMemo(() => {\n const actions: ActionItem[] = [];\n\n baseActions.forEach((action) => {\n if (action === HeaderAction.Folding) {\n if (handleFolding) {\n actions.push({\n id: action,\n type: 'base',\n onClick: () => {\n const newState = foldingState === 'opened' ? 'collapsed' : 'opened';\n handleFolding(newState);\n },\n foldingState,\n });\n }\n return;\n }\n\n const actionMap: Partial<Record<HeaderAction, () => void>> = {\n [HeaderAction.NewChat]: handleNewChat,\n [HeaderAction.History]: handleHistoryToggle,\n [HeaderAction.Close]: handleClose,\n };\n\n const handler = actionMap[action];\n if (handler) {\n actions.push({\n id: action,\n type: 'base',\n onClick: handler,\n });\n }\n });\n\n return actions;\n }, [baseActions, handleNewChat, handleHistoryToggle, handleClose, handleFolding, foldingState]);\n\n return {\n title,\n preview,\n icon,\n baseActions: baseActionsList,\n additionalActions,\n actionsPlacement,\n actionsOrder,\n actionSize,\n isMobile,\n actionIcons,\n titlePosition,\n withIcon,\n showTitle,\n className,\n historyButtonRef,\n qa,\n actionQa,\n actionTooltipTexts,\n menuItems,\n menuButtonTooltip,\n menuButtonIcon,\n menuButtonQa,\n menuItemQa,\n };\n}\n"]}
1
+ {"version":3,"file":"useHeader.js","sourceRoot":"../../../../../src","sources":["components/organisms/Header/useHeader.ts"],"names":[],"mappings":";;AAeA,8BAuHC;AAtID,iCAAqC;AAErC,6CAA4C;AAI5C,sCAA4E;AAS5E,SAAgB,SAAS,CAAC,KAAkB;IAwBxC,MAAM,EACF,IAAI,EACJ,KAAK,EACL,OAAO,EACP,WAAW,GAAG,EAAE,EAChB,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,YAAY,GAAG,QAAQ,EACvB,iBAAiB,GAAG,EAAE,EACtB,gBAAgB,GAAG,EAAE,EACrB,YAAY,GAAG,EAAE,EACjB,UAAU,EAAE,cAAc,EAC1B,SAAS,GAAG,EAAE,EACd,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,aAAa,GAAG,MAAM,EACtB,QAAQ,GAAG,IAAI,EACf,SAAS,GAAG,IAAI,EAChB,SAAS,EACT,gBAAgB,EAChB,EAAE,EACF,QAAQ,EACR,kBAAkB,GACrB,GAAG,KAAK,CAAC;IAEV,MAAM,QAAQ,GAAG,IAAA,iBAAS,GAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAE7D,qBAAqB;IACrB,MAAM,eAAe,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QACjC,MAAM,OAAO,GAAiB,EAAE,CAAC;QAEjC,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAC3B,IAAI,MAAM,KAAK,oBAAY,CAAC,OAAO,EAAE,CAAC;gBAClC,IAAI,aAAa,EAAE,CAAC;oBAChB,OAAO,CAAC,IAAI,CAAC;wBACT,EAAE,EAAE,MAAM;wBACV,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,GAAG,EAAE;4BACV,MAAM,QAAQ,GAAG,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;4BACpE,aAAa,CAAC,QAAQ,CAAC,CAAC;wBAC5B,CAAC;wBACD,YAAY;qBACf,CAAC,CAAC;gBACP,CAAC;gBACD,OAAO;YACX,CAAC;YAED,MAAM,SAAS,GAA8C;gBACzD,CAAC,oBAAY,CAAC,OAAO,CAAC,EAAE,aAAa;gBACrC,CAAC,oBAAY,CAAC,OAAO,CAAC,EAAE,mBAAmB;gBAC3C,CAAC,oBAAY,CAAC,KAAK,CAAC,EAAE,WAAW;aACpC,CAAC;YAEF,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YAClC,IAAI,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC;oBACT,EAAE,EAAE,MAAM;oBACV,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,OAAO;iBACnB,CAAC,CAAC;YACP,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;IACnB,CAAC,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;IAEhG,OAAO;QACH,KAAK;QACL,OAAO;QACP,IAAI;QACJ,WAAW,EAAE,eAAe;QAC5B,iBAAiB;QACjB,gBAAgB;QAChB,YAAY;QACZ,UAAU;QACV,QAAQ;QACR,aAAa;QACb,QAAQ;QACR,SAAS;QACT,SAAS;QACT,gBAAgB;QAChB,EAAE;QACF,QAAQ;QACR,kBAAkB;QAClB,SAAS;QACT,iBAAiB;QACjB,cAAc;QACd,YAAY;QACZ,UAAU;KACb,CAAC;AACN,CAAC","sourcesContent":["import React, {useMemo} from 'react';\n\nimport {useMobile} from '@gravity-ui/uikit';\n\nimport type {Action} from '../../../types/common';\n\nimport {HeaderAction, type HeaderMenuItem, type HeaderProps} from './types';\n\nexport type ActionItem = {\n id: string;\n type: 'base' | 'additional';\n onClick?: () => void;\n foldingState?: 'collapsed' | 'opened';\n};\n\nexport function useHeader(props: HeaderProps): {\n title: string | undefined;\n preview: React.ReactNode | undefined;\n icon: React.ReactNode | undefined;\n baseActions: ActionItem[];\n additionalActions: Action[];\n actionsPlacement: NonNullable<HeaderProps['actionsPlacement']>;\n actionsOrder: NonNullable<HeaderProps['actionsOrder']>;\n actionSize: NonNullable<HeaderProps['actionSize']>;\n isMobile: boolean;\n titlePosition: 'left' | 'center';\n withIcon: boolean;\n showTitle: boolean;\n className?: string;\n historyButtonRef?: React.RefObject<HTMLElement>;\n qa?: string;\n actionQa?: HeaderProps['actionQa'];\n actionTooltipTexts?: HeaderProps['actionTooltipTexts'];\n menuItems: HeaderMenuItem[];\n menuButtonTooltip?: string;\n menuButtonIcon?: React.ReactNode;\n menuButtonQa?: string;\n menuItemQa?: HeaderProps['menuItemQa'];\n} {\n const {\n icon,\n title,\n preview,\n baseActions = [],\n handleNewChat,\n handleHistoryToggle,\n handleClose,\n handleFolding,\n foldingState = 'opened',\n additionalActions = [],\n actionsPlacement = {},\n actionsOrder = {},\n actionSize: actionSizeProp,\n menuItems = [],\n menuButtonTooltip,\n menuButtonIcon,\n menuButtonQa,\n menuItemQa,\n titlePosition = 'left',\n withIcon = true,\n showTitle = true,\n className,\n historyButtonRef,\n qa,\n actionQa,\n actionTooltipTexts,\n } = props;\n\n const isMobile = useMobile();\n const actionSize = actionSizeProp ?? (isMobile ? 'xl' : 'm');\n\n // Build base actions\n const baseActionsList = useMemo(() => {\n const actions: ActionItem[] = [];\n\n baseActions.forEach((action) => {\n if (action === HeaderAction.Folding) {\n if (handleFolding) {\n actions.push({\n id: action,\n type: 'base',\n onClick: () => {\n const newState = foldingState === 'opened' ? 'collapsed' : 'opened';\n handleFolding(newState);\n },\n foldingState,\n });\n }\n return;\n }\n\n const actionMap: Partial<Record<HeaderAction, () => void>> = {\n [HeaderAction.NewChat]: handleNewChat,\n [HeaderAction.History]: handleHistoryToggle,\n [HeaderAction.Close]: handleClose,\n };\n\n const handler = actionMap[action];\n if (handler) {\n actions.push({\n id: action,\n type: 'base',\n onClick: handler,\n });\n }\n });\n\n return actions;\n }, [baseActions, handleNewChat, handleHistoryToggle, handleClose, handleFolding, foldingState]);\n\n return {\n title,\n preview,\n icon,\n baseActions: baseActionsList,\n additionalActions,\n actionsPlacement,\n actionsOrder,\n actionSize,\n isMobile,\n titlePosition,\n withIcon,\n showTitle,\n className,\n historyButtonRef,\n qa,\n actionQa,\n actionTooltipTexts,\n menuItems,\n menuButtonTooltip,\n menuButtonIcon,\n menuButtonQa,\n menuItemQa,\n };\n}\n"]}
@@ -57,7 +57,7 @@
57
57
  flex-direction: column;
58
58
  align-items: flex-start;
59
59
  justify-content: flex-start;
60
- padding: var(--g-aikit-message-list-footer-content-padding);
60
+ padding: var(--g-spacing-4) 0 var(--g-spacing-2);
61
61
  }
62
62
  .g-aikit-message-list__retry-button {
63
63
  display: flex;
@@ -18,7 +18,6 @@
18
18
  flex-direction: column;
19
19
  align-self: stretch;
20
20
  min-height: 0;
21
- overflow-y: var(--g-aikit-empty-container-content-overflow-y);
22
21
  justify-content: var(--g-aikit-empty-container-content-justify-content);
23
22
  gap: var(--g-aikit-empty-container-content-gap);
24
23
  padding: var(--g-aikit-empty-container-padding);
@@ -75,7 +74,8 @@
75
74
  }
76
75
  .g-aikit-empty-container__suggestions-list {
77
76
  flex: 1 1 auto;
78
- min-height: var(--g-aikit-empty-container-suggestions-list-min-height);
77
+ min-height: 70px;
78
+ overflow-y: auto;
79
79
  }
80
80
  .g-aikit-empty-container__show-more {
81
81
  display: flex;
@@ -1,16 +1,12 @@
1
- import { DateLocaleConfig } from "../../../hooks/index.js";
2
1
  /**
3
2
  * Props for DateHeaderItem component
4
3
  */
5
4
  export interface DateHeaderItemProps {
6
5
  date: string;
7
- format?: string;
8
- locale?: string;
9
- localeConfig?: DateLocaleConfig;
10
6
  }
11
7
  /**
12
8
  * Date header component for grouping chats
13
9
  *
14
10
  * @returns React element
15
11
  */
16
- export declare function DateHeaderItem({ date, format, locale, localeConfig }: DateHeaderItemProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function DateHeaderItem({ date }: DateHeaderItemProps): import("react/jsx-runtime").JSX.Element;
@@ -10,7 +10,7 @@ const b = (0, cn_1.block)('history');
10
10
  *
11
11
  * @returns React element
12
12
  */
13
- function DateHeaderItem({ date, format, locale, localeConfig }) {
14
- return ((0, jsx_runtime_1.jsx)("div", { className: b('date-header'), children: (0, jsx_runtime_1.jsx)(ChatDate_1.ChatDate, { date: new Date(date), format: format, locale: locale, localeConfig: localeConfig, relative: true }) }));
13
+ function DateHeaderItem({ date }) {
14
+ return ((0, jsx_runtime_1.jsx)("div", { className: b('date-header'), children: (0, jsx_runtime_1.jsx)(ChatDate_1.ChatDate, { date: new Date(date), relative: true }) }));
15
15
  }
16
16
  //# sourceMappingURL=DateHeaderItem.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DateHeaderItem.js","sourceRoot":"../../../../../src","sources":["components/templates/History/DateHeaderItem.tsx"],"names":[],"mappings":";;AAqBA,wCAYC;;AAhCD,6CAAwC;AACxC,4DAA8C;AAE9C,MAAM,CAAC,GAAG,IAAA,UAAK,EAAC,SAAS,CAAC,CAAC;AAY3B;;;;GAIG;AACH,SAAgB,cAAc,CAAC,EAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAsB;IACpF,OAAO,CACH,gCAAK,SAAS,EAAE,CAAC,CAAC,aAAa,CAAC,YAC5B,uBAAC,mBAAQ,IACL,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,QAAQ,SACV,GACA,CACT,CAAC;AACN,CAAC","sourcesContent":["import {DateLocaleConfig} from '../../../hooks';\nimport {block} from '../../../utils/cn';\nimport {ChatDate} from '../../atoms/ChatDate';\n\nconst b = block('history');\n\n/**\n * Props for DateHeaderItem component\n */\nexport interface DateHeaderItemProps {\n date: string;\n format?: string;\n locale?: string;\n localeConfig?: DateLocaleConfig;\n}\n\n/**\n * Date header component for grouping chats\n *\n * @returns React element\n */\nexport function DateHeaderItem({date, format, locale, localeConfig}: DateHeaderItemProps) {\n return (\n <div className={b('date-header')}>\n <ChatDate\n date={new Date(date)}\n format={format}\n locale={locale}\n localeConfig={localeConfig}\n relative\n />\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"DateHeaderItem.js","sourceRoot":"../../../../../src","sources":["components/templates/History/DateHeaderItem.tsx"],"names":[],"mappings":";;AAiBA,wCAMC;;AAvBD,6CAAwC;AACxC,4DAA8C;AAE9C,MAAM,CAAC,GAAG,IAAA,UAAK,EAAC,SAAS,CAAC,CAAC;AAS3B;;;;GAIG;AACH,SAAgB,cAAc,CAAC,EAAC,IAAI,EAAsB;IACtD,OAAO,CACH,gCAAK,SAAS,EAAE,CAAC,CAAC,aAAa,CAAC,YAC5B,uBAAC,mBAAQ,IAAC,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,SAAG,GACzC,CACT,CAAC;AACN,CAAC","sourcesContent":["import {block} from '../../../utils/cn';\nimport {ChatDate} from '../../atoms/ChatDate';\n\nconst b = block('history');\n\n/**\n * Props for DateHeaderItem component\n */\nexport interface DateHeaderItemProps {\n date: string;\n}\n\n/**\n * Date header component for grouping chats\n *\n * @returns React element\n */\nexport function DateHeaderItem({date}: DateHeaderItemProps) {\n return (\n <div className={b('date-header')}>\n <ChatDate date={new Date(date)} relative />\n </div>\n );\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
2
  import { DOMProps, InputControlSize, QAProps } from '@gravity-ui/uikit';
3
- import { DateLocaleConfig } from "../../../hooks/index.js";
4
3
  import { ChatType } from "../../../types/index.js";
5
4
  import { ChatFilterFunction } from "../../../utils/chatUtils.js";
6
5
  import "./History.css";
@@ -42,12 +41,6 @@ export interface HistoryListProps extends QAProps, DOMProps {
42
41
  searchable?: boolean;
43
42
  /** Group chats by date or none */
44
43
  groupBy?: 'date' | 'none';
45
- /** Custom dayjs format for non-relative date headers */
46
- dateFormat?: string;
47
- /** Locale for non-relative date headers */
48
- dateLocale?: string;
49
- /** Dayjs locale configuration for non-relative date headers */
50
- dateLocaleConfig?: DateLocaleConfig;
51
44
  /** Show action buttons (delete, etc.) */
52
45
  showActions?: boolean;
53
46
  /** Empty state placeholder */
@@ -21,7 +21,7 @@ const b = (0, cn_1.block)('history');
21
21
  * @returns Rendered history list (search, grouping, lazy/full load, chat rows).
22
22
  */
23
23
  function HistoryList(props) {
24
- const { chats, selectedChat, onSelectChat, onDeleteChat, onLoadMore, hasMore = false, loadMode = 'full', searchable = true, groupBy = 'date', dateFormat, dateLocale, dateLocaleConfig, showActions = true, emptyPlaceholder, emptyFilteredPlaceholder, searchPlaceholder, className, qa, style, filterFunction = chatUtils_1.defaultChatFilter, loading = false, onChatClick, size = 'm', } = props;
24
+ const { chats, selectedChat, onSelectChat, onDeleteChat, onLoadMore, hasMore = false, loadMode = 'full', searchable = true, groupBy = 'date', showActions = true, emptyPlaceholder, emptyFilteredPlaceholder, searchPlaceholder, className, qa, style, filterFunction = chatUtils_1.defaultChatFilter, loading = false, onChatClick, size = 'm', } = props;
25
25
  const [filteredItemCount, setFilteredItemCount] = (0, react_1.useState)(null);
26
26
  const [loadedChats, setLoadedChats] = (0, react_1.useState)([]);
27
27
  const [lazyHasMore, setLazyHasMore] = (0, react_1.useState)(hasMore);
@@ -140,7 +140,7 @@ function HistoryList(props) {
140
140
  }, [filterFunction]);
141
141
  const renderItem = (item, isActive) => {
142
142
  if (item.type === 'date-header') {
143
- return ((0, jsx_runtime_1.jsx)(DateHeaderItem_1.DateHeaderItem, { date: item.date, format: dateFormat, locale: dateLocale, localeConfig: dateLocaleConfig }, `date-${item.date}`));
143
+ return (0, jsx_runtime_1.jsx)(DateHeaderItem_1.DateHeaderItem, { date: item.date }, `date-${item.date}`);
144
144
  }
145
145
  return ((0, jsx_runtime_1.jsx)(ChatItem_1.ChatItem, { chat: item, showActions: showActions, onDeleteClick: onDeleteChat ? handleDeleteClick : undefined, isActive: isActive }, item.id));
146
146
  };
@@ -1 +1 @@
1
- {"version":3,"file":"HistoryList.js","sourceRoot":"../../../../../src","sources":["components/templates/History/HistoryList.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';\n\nimport {Button, DOMProps, InputControlSize, List, ListItemData, QAProps} from '@gravity-ui/uikit';\n\nimport {DateLocaleConfig} from '../../../hooks';\nimport {ChatType, ListItemChatData} from '../../../types';\nimport {ChatFilterFunction, defaultChatFilter, groupChatsByDate} from '../../../utils/chatUtils';\nimport {block} from '../../../utils/cn';\nimport {IntersectionContainer} from '../../atoms/IntersectionContainer';\nimport {Loader} from '../../atoms/Loader';\n\nimport {ChatItem} from './ChatItem';\nimport {DateHeaderItem} from './DateHeaderItem';\nimport {i18n} from './i18n';\n\nimport './History.scss';\n\nconst b = block('history');\n\n/** Result of lazy load more callback - either array of new chats or object with chats and hasMore flag */\nexport type LoadMoreLazyResult = ChatType[] | {chats: ChatType[]; hasMore?: boolean};\n\n/** Callback for lazy load more - returns only new chats, not previously loaded */\nexport type OnLoadMoreLazy = (offset: number) => Promise<LoadMoreLazyResult>;\n\n/** Load mode: full (button, parent manages all data) or lazy (scroll, component accumulates data) */\nexport type HistoryLoadMode = 'full' | 'lazy';\n\n/**\n * Props for the HistoryList component\n */\nexport interface HistoryListProps extends QAProps, DOMProps {\n /** Array of chat items */\n chats: ChatType[];\n /** Currently selected chat */\n selectedChat?: ChatType | null;\n /** Callback when a chat is selected */\n onSelectChat?: (chat: ChatType) => void;\n /** Callback when a chat is deleted */\n onDeleteChat?: (chat: ChatType) => Promise<void>;\n /**\n * Callback to load more chats.\n * - Full mode: () => void - triggers load, parent updates chats prop\n * - Lazy mode: (offset) => Promise<ChatType[]|{chats,hasMore}> - returns only new chats\n */\n onLoadMore?: (() => void) | OnLoadMoreLazy;\n /** Whether there are more chats to load */\n hasMore?: boolean;\n /**\n * Load mode: 'full' (button click, parent provides all data) or 'lazy' (scroll, callback returns new data only)\n * @default 'full'\n */\n loadMode?: HistoryLoadMode;\n /** Enable search functionality */\n searchable?: boolean;\n /** Group chats by date or none */\n groupBy?: 'date' | 'none';\n /** Custom dayjs format for non-relative date headers */\n dateFormat?: string;\n /** Locale for non-relative date headers */\n dateLocale?: string;\n /** Dayjs locale configuration for non-relative date headers */\n dateLocaleConfig?: DateLocaleConfig;\n /** Show action buttons (delete, etc.) */\n showActions?: boolean;\n /** Empty state placeholder */\n emptyPlaceholder?: React.ReactNode;\n /** Empty filtered state placeholder (when search returns no results) */\n emptyFilteredPlaceholder?: React.ReactNode;\n /** Placeholder text for the search/filter input (defaults to built-in i18n string) */\n searchPlaceholder?: string;\n /** Additional CSS class */\n className?: string;\n /** Custom filter function for search */\n filterFunction?: ChatFilterFunction;\n /** Loading state */\n loading?: boolean;\n /** Callback when chat is clicked (for closing popup in parent) */\n onChatClick?: (chat: ChatType) => void;\n /** Size of the list */\n size?: InputControlSize;\n}\n\n/**\n * HistoryList component - displays a list of chats with search, grouping, and actions\n *\n * @param props - {@link HistoryListProps}\n * @returns Rendered history list (search, grouping, lazy/full load, chat rows).\n */\nexport function HistoryList(props: HistoryListProps) {\n const {\n chats,\n selectedChat,\n onSelectChat,\n onDeleteChat,\n onLoadMore,\n hasMore = false,\n loadMode = 'full',\n searchable = true,\n groupBy = 'date',\n dateFormat,\n dateLocale,\n dateLocaleConfig,\n showActions = true,\n emptyPlaceholder,\n emptyFilteredPlaceholder,\n searchPlaceholder,\n className,\n qa,\n style,\n filterFunction = defaultChatFilter,\n loading = false,\n onChatClick,\n size = 'm',\n } = props;\n\n const [filteredItemCount, setFilteredItemCount] = useState<number | null>(null);\n const [loadedChats, setLoadedChats] = useState<ChatType[]>([]);\n const [lazyHasMore, setLazyHasMore] = useState(hasMore);\n const [deletedChats, setDeletedChats] = useState<Set<string>>(new Set());\n\n const loadingMoreRef = useRef(false);\n\n const displayChats = useMemo(() => {\n const totalChats = loadMode === 'lazy' ? [...chats, ...loadedChats] : chats;\n\n const filteredChats = totalChats.filter((chat) => !deletedChats.has(chat.id));\n\n return filteredChats;\n }, [loadMode, chats, loadedChats, deletedChats]);\n\n const displayChatsLengthRef = useRef(displayChats.length);\n displayChatsLengthRef.current = displayChats.length;\n\n useEffect(() => {\n if (loadMode === 'lazy') {\n setLazyHasMore(hasMore);\n }\n }, [loadMode, hasMore]);\n\n useEffect(() => {\n if (loadMode === 'lazy') {\n setLoadedChats([]);\n }\n }, [chats, loadMode]);\n\n const groupedChats = useMemo(() => {\n if (groupBy === 'none') {\n return new Map([['all', displayChats]]);\n }\n return groupChatsByDate(displayChats);\n }, [displayChats, groupBy]);\n\n const listItems: ListItemData<ListItemChatData>[] = useMemo(() => {\n const items: ListItemData<ListItemChatData>[] = [];\n\n const sortedGroups = Array.from(groupedChats.entries()).sort(([dateA], [dateB]) => {\n if (dateA === 'all') return 0;\n return new Date(dateB).getTime() - new Date(dateA).getTime();\n });\n\n sortedGroups.forEach(([dateKey, groupChats]) => {\n if (groupChats.length === 0) {\n return;\n }\n\n if (groupBy === 'date' && dateKey !== 'all') {\n items.push({\n type: 'date-header',\n disabled: true,\n date: dateKey,\n });\n }\n\n groupChats.forEach((chat) => {\n items.push({\n type: 'chat',\n ...chat,\n });\n });\n });\n\n return items;\n }, [groupedChats, groupBy]);\n\n const selectedItemIndex = useMemo(() => {\n return listItems.findIndex((item) => item.type === 'chat' && item.id === selectedChat?.id);\n }, [listItems, selectedChat]);\n\n const effectiveHasMore = loadMode === 'lazy' ? lazyHasMore : hasMore;\n\n /**\n * Unified load more handler.\n * full: fires onLoadMore(), parent manages data and hasMore\n * lazy: calls onLoadMore(offset), accumulates returned chats internally\n */\n const handleLoadMore = useCallback(async () => {\n if (!onLoadMore || loadingMoreRef.current) {\n return;\n }\n\n if (loadMode === 'full') {\n (onLoadMore as () => void)();\n return;\n }\n\n loadingMoreRef.current = true;\n try {\n const offset = displayChatsLengthRef.current;\n const result = await (onLoadMore as OnLoadMoreLazy)(offset);\n const newChats = Array.isArray(result) ? result : result.chats;\n const resultHasMore = Array.isArray(result) ? newChats.length > 0 : result.hasMore;\n setLoadedChats((prev) => [...prev, ...newChats]);\n setLazyHasMore(resultHasMore ?? newChats.length > 0);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('HistoryList: failed to load more chats', error);\n } finally {\n loadingMoreRef.current = false;\n }\n }, [onLoadMore, loadMode]);\n\n const handleChatClick = (\n chat: ListItemData<ListItemChatData>,\n _: number,\n fromKeyboard?: boolean,\n event?: React.KeyboardEvent<HTMLElement> | React.MouseEvent<HTMLElement>,\n ) => {\n if (fromKeyboard && (event?.target as HTMLButtonElement)?.type === 'button') {\n return;\n }\n onSelectChat?.(chat as ChatType);\n onChatClick?.(chat as ChatType);\n };\n\n const handleDeleteClick = async (e: React.MouseEvent, chat: ChatType) => {\n e.stopPropagation();\n try {\n await onDeleteChat?.(chat);\n setDeletedChats((prevDeletedChats) => new Set([...prevDeletedChats, chat.id]));\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('HistoryList: failed to delete chat', error);\n }\n };\n\n const wrappedFilterFunction = useMemo(() => {\n return (filter: string) => {\n const userFilter = filterFunction(filter);\n return (item: ListItemData<ListItemChatData>): boolean => {\n if (filter && item.type === 'date-header') {\n return false;\n }\n return userFilter(item);\n };\n };\n }, [filterFunction]);\n\n const renderItem = (item: ListItemData<ListItemChatData>, isActive: boolean) => {\n if (item.type === 'date-header') {\n return (\n <DateHeaderItem\n key={`date-${item.date}`}\n date={item.date}\n format={dateFormat}\n locale={dateLocale}\n localeConfig={dateLocaleConfig}\n />\n );\n }\n\n return (\n <ChatItem\n key={item.id}\n chat={item}\n showActions={showActions}\n onDeleteClick={onDeleteChat ? handleDeleteClick : undefined}\n isActive={isActive}\n />\n );\n };\n\n const emptyState = emptyPlaceholder || <div className={b('empty')}>{i18n('empty-state')}</div>;\n\n const emptyFilteredState = emptyFilteredPlaceholder || (\n <div className={b('empty')}>{i18n('empty-filtered-state')}</div>\n );\n\n const finalEmptyPlaceholder =\n filteredItemCount === null || filteredItemCount === listItems.length\n ? emptyState\n : emptyFilteredState;\n\n return (\n <div className={b('container', className)} data-qa={qa} style={style}>\n <div className={b('list-wrapper')}>\n {loading ? (\n <div className={b('loader-wrapper')}>\n <Loader view=\"loading\" />\n </div>\n ) : (\n <React.Fragment>\n <List\n size={size}\n items={listItems}\n renderItem={renderItem}\n virtualized={false}\n filterable={searchable}\n filterItem={wrappedFilterFunction}\n filterPlaceholder={searchPlaceholder ?? i18n('search-placeholder')}\n filterClassName={b('filter')}\n emptyPlaceholder={finalEmptyPlaceholder}\n selectedItemIndex={selectedItemIndex}\n itemsClassName={b('list')}\n itemClassName={b('list-item')}\n onFilterEnd={(data) => setFilteredItemCount(data.items.length)}\n onItemClick={handleChatClick}\n />\n {loadMode === 'lazy' && effectiveHasMore && onLoadMore && (\n <IntersectionContainer\n key={displayChats.length}\n onIntersect={handleLoadMore}\n className={b('lazy-loader')}\n >\n <Loader view=\"loading\" />\n </IntersectionContainer>\n )}\n </React.Fragment>\n )}\n </div>\n\n {loadMode === 'full' && hasMore && onLoadMore && (\n <Button view=\"flat-action\" size=\"m\" width=\"max\" onClick={handleLoadMore}>\n {i18n('action-load-more')}\n </Button>\n )}\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"HistoryList.js","sourceRoot":"../../../../../src","sources":["components/templates/History/HistoryList.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';\n\nimport {Button, DOMProps, InputControlSize, List, ListItemData, QAProps} from '@gravity-ui/uikit';\n\nimport {ChatType, ListItemChatData} from '../../../types';\nimport {ChatFilterFunction, defaultChatFilter, groupChatsByDate} from '../../../utils/chatUtils';\nimport {block} from '../../../utils/cn';\nimport {IntersectionContainer} from '../../atoms/IntersectionContainer';\nimport {Loader} from '../../atoms/Loader';\n\nimport {ChatItem} from './ChatItem';\nimport {DateHeaderItem} from './DateHeaderItem';\nimport {i18n} from './i18n';\n\nimport './History.scss';\n\nconst b = block('history');\n\n/** Result of lazy load more callback - either array of new chats or object with chats and hasMore flag */\nexport type LoadMoreLazyResult = ChatType[] | {chats: ChatType[]; hasMore?: boolean};\n\n/** Callback for lazy load more - returns only new chats, not previously loaded */\nexport type OnLoadMoreLazy = (offset: number) => Promise<LoadMoreLazyResult>;\n\n/** Load mode: full (button, parent manages all data) or lazy (scroll, component accumulates data) */\nexport type HistoryLoadMode = 'full' | 'lazy';\n\n/**\n * Props for the HistoryList component\n */\nexport interface HistoryListProps extends QAProps, DOMProps {\n /** Array of chat items */\n chats: ChatType[];\n /** Currently selected chat */\n selectedChat?: ChatType | null;\n /** Callback when a chat is selected */\n onSelectChat?: (chat: ChatType) => void;\n /** Callback when a chat is deleted */\n onDeleteChat?: (chat: ChatType) => Promise<void>;\n /**\n * Callback to load more chats.\n * - Full mode: () => void - triggers load, parent updates chats prop\n * - Lazy mode: (offset) => Promise<ChatType[]|{chats,hasMore}> - returns only new chats\n */\n onLoadMore?: (() => void) | OnLoadMoreLazy;\n /** Whether there are more chats to load */\n hasMore?: boolean;\n /**\n * Load mode: 'full' (button click, parent provides all data) or 'lazy' (scroll, callback returns new data only)\n * @default 'full'\n */\n loadMode?: HistoryLoadMode;\n /** Enable search functionality */\n searchable?: boolean;\n /** Group chats by date or none */\n groupBy?: 'date' | 'none';\n /** Show action buttons (delete, etc.) */\n showActions?: boolean;\n /** Empty state placeholder */\n emptyPlaceholder?: React.ReactNode;\n /** Empty filtered state placeholder (when search returns no results) */\n emptyFilteredPlaceholder?: React.ReactNode;\n /** Placeholder text for the search/filter input (defaults to built-in i18n string) */\n searchPlaceholder?: string;\n /** Additional CSS class */\n className?: string;\n /** Custom filter function for search */\n filterFunction?: ChatFilterFunction;\n /** Loading state */\n loading?: boolean;\n /** Callback when chat is clicked (for closing popup in parent) */\n onChatClick?: (chat: ChatType) => void;\n /** Size of the list */\n size?: InputControlSize;\n}\n\n/**\n * HistoryList component - displays a list of chats with search, grouping, and actions\n *\n * @param props - {@link HistoryListProps}\n * @returns Rendered history list (search, grouping, lazy/full load, chat rows).\n */\nexport function HistoryList(props: HistoryListProps) {\n const {\n chats,\n selectedChat,\n onSelectChat,\n onDeleteChat,\n onLoadMore,\n hasMore = false,\n loadMode = 'full',\n searchable = true,\n groupBy = 'date',\n showActions = true,\n emptyPlaceholder,\n emptyFilteredPlaceholder,\n searchPlaceholder,\n className,\n qa,\n style,\n filterFunction = defaultChatFilter,\n loading = false,\n onChatClick,\n size = 'm',\n } = props;\n\n const [filteredItemCount, setFilteredItemCount] = useState<number | null>(null);\n const [loadedChats, setLoadedChats] = useState<ChatType[]>([]);\n const [lazyHasMore, setLazyHasMore] = useState(hasMore);\n const [deletedChats, setDeletedChats] = useState<Set<string>>(new Set());\n\n const loadingMoreRef = useRef(false);\n\n const displayChats = useMemo(() => {\n const totalChats = loadMode === 'lazy' ? [...chats, ...loadedChats] : chats;\n\n const filteredChats = totalChats.filter((chat) => !deletedChats.has(chat.id));\n\n return filteredChats;\n }, [loadMode, chats, loadedChats, deletedChats]);\n\n const displayChatsLengthRef = useRef(displayChats.length);\n displayChatsLengthRef.current = displayChats.length;\n\n useEffect(() => {\n if (loadMode === 'lazy') {\n setLazyHasMore(hasMore);\n }\n }, [loadMode, hasMore]);\n\n useEffect(() => {\n if (loadMode === 'lazy') {\n setLoadedChats([]);\n }\n }, [chats, loadMode]);\n\n const groupedChats = useMemo(() => {\n if (groupBy === 'none') {\n return new Map([['all', displayChats]]);\n }\n return groupChatsByDate(displayChats);\n }, [displayChats, groupBy]);\n\n const listItems: ListItemData<ListItemChatData>[] = useMemo(() => {\n const items: ListItemData<ListItemChatData>[] = [];\n\n const sortedGroups = Array.from(groupedChats.entries()).sort(([dateA], [dateB]) => {\n if (dateA === 'all') return 0;\n return new Date(dateB).getTime() - new Date(dateA).getTime();\n });\n\n sortedGroups.forEach(([dateKey, groupChats]) => {\n if (groupChats.length === 0) {\n return;\n }\n\n if (groupBy === 'date' && dateKey !== 'all') {\n items.push({\n type: 'date-header',\n disabled: true,\n date: dateKey,\n });\n }\n\n groupChats.forEach((chat) => {\n items.push({\n type: 'chat',\n ...chat,\n });\n });\n });\n\n return items;\n }, [groupedChats, groupBy]);\n\n const selectedItemIndex = useMemo(() => {\n return listItems.findIndex((item) => item.type === 'chat' && item.id === selectedChat?.id);\n }, [listItems, selectedChat]);\n\n const effectiveHasMore = loadMode === 'lazy' ? lazyHasMore : hasMore;\n\n /**\n * Unified load more handler.\n * full: fires onLoadMore(), parent manages data and hasMore\n * lazy: calls onLoadMore(offset), accumulates returned chats internally\n */\n const handleLoadMore = useCallback(async () => {\n if (!onLoadMore || loadingMoreRef.current) {\n return;\n }\n\n if (loadMode === 'full') {\n (onLoadMore as () => void)();\n return;\n }\n\n loadingMoreRef.current = true;\n try {\n const offset = displayChatsLengthRef.current;\n const result = await (onLoadMore as OnLoadMoreLazy)(offset);\n const newChats = Array.isArray(result) ? result : result.chats;\n const resultHasMore = Array.isArray(result) ? newChats.length > 0 : result.hasMore;\n setLoadedChats((prev) => [...prev, ...newChats]);\n setLazyHasMore(resultHasMore ?? newChats.length > 0);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('HistoryList: failed to load more chats', error);\n } finally {\n loadingMoreRef.current = false;\n }\n }, [onLoadMore, loadMode]);\n\n const handleChatClick = (\n chat: ListItemData<ListItemChatData>,\n _: number,\n fromKeyboard?: boolean,\n event?: React.KeyboardEvent<HTMLElement> | React.MouseEvent<HTMLElement>,\n ) => {\n if (fromKeyboard && (event?.target as HTMLButtonElement)?.type === 'button') {\n return;\n }\n onSelectChat?.(chat as ChatType);\n onChatClick?.(chat as ChatType);\n };\n\n const handleDeleteClick = async (e: React.MouseEvent, chat: ChatType) => {\n e.stopPropagation();\n try {\n await onDeleteChat?.(chat);\n setDeletedChats((prevDeletedChats) => new Set([...prevDeletedChats, chat.id]));\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('HistoryList: failed to delete chat', error);\n }\n };\n\n const wrappedFilterFunction = useMemo(() => {\n return (filter: string) => {\n const userFilter = filterFunction(filter);\n return (item: ListItemData<ListItemChatData>): boolean => {\n if (filter && item.type === 'date-header') {\n return false;\n }\n return userFilter(item);\n };\n };\n }, [filterFunction]);\n\n const renderItem = (item: ListItemData<ListItemChatData>, isActive: boolean) => {\n if (item.type === 'date-header') {\n return <DateHeaderItem key={`date-${item.date}`} date={item.date} />;\n }\n\n return (\n <ChatItem\n key={item.id}\n chat={item}\n showActions={showActions}\n onDeleteClick={onDeleteChat ? handleDeleteClick : undefined}\n isActive={isActive}\n />\n );\n };\n\n const emptyState = emptyPlaceholder || <div className={b('empty')}>{i18n('empty-state')}</div>;\n\n const emptyFilteredState = emptyFilteredPlaceholder || (\n <div className={b('empty')}>{i18n('empty-filtered-state')}</div>\n );\n\n const finalEmptyPlaceholder =\n filteredItemCount === null || filteredItemCount === listItems.length\n ? emptyState\n : emptyFilteredState;\n\n return (\n <div className={b('container', className)} data-qa={qa} style={style}>\n <div className={b('list-wrapper')}>\n {loading ? (\n <div className={b('loader-wrapper')}>\n <Loader view=\"loading\" />\n </div>\n ) : (\n <React.Fragment>\n <List\n size={size}\n items={listItems}\n renderItem={renderItem}\n virtualized={false}\n filterable={searchable}\n filterItem={wrappedFilterFunction}\n filterPlaceholder={searchPlaceholder ?? i18n('search-placeholder')}\n filterClassName={b('filter')}\n emptyPlaceholder={finalEmptyPlaceholder}\n selectedItemIndex={selectedItemIndex}\n itemsClassName={b('list')}\n itemClassName={b('list-item')}\n onFilterEnd={(data) => setFilteredItemCount(data.items.length)}\n onItemClick={handleChatClick}\n />\n {loadMode === 'lazy' && effectiveHasMore && onLoadMore && (\n <IntersectionContainer\n key={displayChats.length}\n onIntersect={handleLoadMore}\n className={b('lazy-loader')}\n >\n <Loader view=\"loading\" />\n </IntersectionContainer>\n )}\n </React.Fragment>\n )}\n </div>\n\n {loadMode === 'full' && hasMore && onLoadMore && (\n <Button view=\"flat-action\" size=\"m\" width=\"max\" onClick={handleLoadMore}>\n {i18n('action-load-more')}\n </Button>\n )}\n </div>\n );\n}\n"]}