@gravity-ui/aikit 2.22.0 → 2.22.1

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.
@@ -1,3 +1,4 @@
1
+ import { type PopupProps } from '@gravity-ui/uikit';
1
2
  import { type HistoryListProps } from "./HistoryList.js";
2
3
  import "./History.css";
3
4
  /**
@@ -12,6 +13,16 @@ export interface HistoryProps extends Omit<HistoryListProps, 'onChatClick'> {
12
13
  anchorElement: HTMLElement | null;
13
14
  /** Show the mobile sheet title (default: `true`); it stays in `aria-label` either way */
14
15
  showSheetTitle?: boolean;
16
+ /**
17
+ * Keep the keyboard focus inside the desktop popup while it is open (default: `true`).
18
+ *
19
+ * The popup is rendered in a portal, so without focus management `Tab` from the trigger
20
+ * button walks through the rest of the page instead of entering the popup, and the chat
21
+ * list cannot be reached from the keyboard at all.
22
+ */
23
+ modal?: boolean;
24
+ /** The element to focus when the desktop popup opens (default: the popup itself) */
25
+ initialFocus?: PopupProps['initialFocus'];
15
26
  }
16
27
  /**
17
28
  * History component - wraps HistoryList in a Popup, and in a bottom Sheet in mobile mode
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.History = History;
4
4
  const tslib_1 = require("tslib");
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = tslib_1.__importDefault(require("react"));
6
7
  const uikit_1 = require("@gravity-ui/uikit");
7
8
  const useSheetKeyboardFit_1 = require("../../../hooks/useSheetKeyboardFit.js");
8
9
  const cn_1 = require("../../../utils/cn.js");
@@ -17,10 +18,15 @@ const b = (0, cn_1.block)('history');
17
18
  * @returns React component
18
19
  */
19
20
  function History(props) {
20
- const { open = false, onOpenChange, anchorElement, showSheetTitle = true } = props, listProps = tslib_1.__rest(props, ["open", "onOpenChange", "anchorElement", "showSheetTitle"]);
21
+ const { open = false, onOpenChange, anchorElement, showSheetTitle = true, modal = true, initialFocus } = props, listProps = tslib_1.__rest(props, ["open", "onOpenChange", "anchorElement", "showSheetTitle", "modal", "initialFocus"]);
21
22
  const isMobile = (0, uikit_1.useMobile)();
22
23
  const sheetId = (0, uikit_1.useUniqId)();
23
24
  const { isKeyboardOpen } = (0, useSheetKeyboardFit_1.useSheetKeyboardFit)(isMobile && open, `.${b('sheet')}`);
25
+ // `Popup` runs its props through uikit's `filterDOMProps` without the `labelable` option, so an
26
+ // `aria-label` passed to it never reaches the floating element. Set it on the element instead.
27
+ const labelPopup = react_1.default.useCallback((node) => {
28
+ node === null || node === void 0 ? void 0 : node.setAttribute('aria-label', (0, i18n_1.i18n)('sheet-title'));
29
+ }, []);
24
30
  const handleChatClick = () => {
25
31
  onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(false);
26
32
  };
@@ -31,6 +37,6 @@ function History(props) {
31
37
  'keyboard-open': isKeyboardOpen,
32
38
  }), qa: "history-sheet", allowHideOnContentScroll: true, children: list }));
33
39
  }
34
- return ((0, jsx_runtime_1.jsx)(uikit_1.Popup, { anchorElement: anchorElement, placement: "bottom-end", open: open, onOpenChange: onOpenChange, children: list }));
40
+ return ((0, jsx_runtime_1.jsx)(uikit_1.Popup, { anchorElement: anchorElement, placement: "bottom-end", open: open, onOpenChange: onOpenChange, modal: modal, initialFocus: initialFocus, floatingRef: labelPopup, children: list }));
35
41
  }
36
42
  //# sourceMappingURL=History.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"History.js","sourceRoot":"../../../../../src","sources":["components/templates/History/History.tsx"],"names":[],"mappings":";;AAgCA,0BA0CC;;;AA1ED,6CAAqE;AAErE,+EAAuE;AACvE,6CAAwC;AAExC,kDAAiE;AACjE,0CAA4B;AAE5B,yBAAwB;AAExB,MAAM,CAAC,GAAG,IAAA,UAAK,EAAC,SAAS,CAAC,CAAC;AAgB3B;;;;;GAKG;AACH,SAAgB,OAAO,CAAC,KAAmB;IACvC,MAAM,EAAC,IAAI,GAAG,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,GAAG,IAAI,KAAkB,KAAK,EAAlB,SAAS,kBAAI,KAAK,EAAxF,2DAAgF,CAAQ,CAAC;IAC/F,MAAM,QAAQ,GAAG,IAAA,iBAAS,GAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,IAAA,iBAAS,GAAE,CAAC;IAC5B,MAAM,EAAC,cAAc,EAAC,GAAG,IAAA,yCAAmB,EAAC,QAAQ,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEjF,MAAM,eAAe,GAAG,GAAG,EAAE;QACzB,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,KAAK,CAAC,CAAC;IAC1B,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,uBAAC,yBAAW,oBAAK,SAAS,IAAE,WAAW,EAAE,eAAe,IAAI,CAAC;IAE1E,IAAI,QAAQ,EAAE,CAAC;QACX,OAAO,CACH,uBAAC,aAAK,IACF,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,IAAA,WAAI,EAAC,aAAa,CAAC,EAC1B,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,KAAK,CAAC,EACpC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,EACrB,gBAAgB,EAAE,CAAC,CAAC,eAAe,EAAE;gBACjC,eAAe,EAAE,CAAC,cAAc;gBAChC,eAAe,EAAE,cAAc;aAClC,CAAC,EACF,EAAE,EAAC,eAAe,EAClB,wBAAwB,kBAEvB,IAAI,GACD,CACX,CAAC;IACN,CAAC;IAED,OAAO,CACH,uBAAC,aAAK,IACF,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAC,YAAY,EACtB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,YAAY,YAEzB,IAAI,GACD,CACX,CAAC;AACN,CAAC","sourcesContent":["import {Popup, Sheet, useMobile, useUniqId} from '@gravity-ui/uikit';\n\nimport {useSheetKeyboardFit} from '../../../hooks/useSheetKeyboardFit';\nimport {block} from '../../../utils/cn';\n\nimport {HistoryList, type HistoryListProps} from './HistoryList';\nimport {i18n} from './i18n';\n\nimport './History.scss';\n\nconst b = block('history');\n\n/**\n * Props for the History component\n */\nexport interface HistoryProps extends Omit<HistoryListProps, 'onChatClick'> {\n /** Control popup open state */\n open?: boolean;\n /** Callback when popup open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Anchor element for the popup */\n anchorElement: HTMLElement | null;\n /** Show the mobile sheet title (default: `true`); it stays in `aria-label` either way */\n showSheetTitle?: boolean;\n}\n\n/**\n * History component - wraps HistoryList in a Popup, and in a bottom Sheet in mobile mode\n *\n * @param props - Component props\n * @returns React component\n */\nexport function History(props: HistoryProps) {\n const {open = false, onOpenChange, anchorElement, showSheetTitle = true, ...listProps} = props;\n const isMobile = useMobile();\n const sheetId = useUniqId();\n const {isKeyboardOpen} = useSheetKeyboardFit(isMobile && open, `.${b('sheet')}`);\n\n const handleChatClick = () => {\n onOpenChange?.(false);\n };\n\n const list = <HistoryList {...listProps} onChatClick={handleChatClick} />;\n\n if (isMobile) {\n return (\n <Sheet\n id={sheetId}\n title={i18n('sheet-title')}\n visible={open}\n onClose={() => onOpenChange?.(false)}\n className={b('sheet')}\n contentClassName={b('sheet-content', {\n 'without-title': !showSheetTitle,\n 'keyboard-open': isKeyboardOpen,\n })}\n qa=\"history-sheet\"\n allowHideOnContentScroll\n >\n {list}\n </Sheet>\n );\n }\n\n return (\n <Popup\n anchorElement={anchorElement}\n placement=\"bottom-end\"\n open={open}\n onOpenChange={onOpenChange}\n >\n {list}\n </Popup>\n );\n}\n"]}
1
+ {"version":3,"file":"History.js","sourceRoot":"../../../../../src","sources":["components/templates/History/History.tsx"],"names":[],"mappings":";;AA4CA,0BA2DC;;;AAvGD,0DAA0B;AAE1B,6CAAsF;AAEtF,+EAAuE;AACvE,6CAAwC;AAExC,kDAAiE;AACjE,0CAA4B;AAE5B,yBAAwB;AAExB,MAAM,CAAC,GAAG,IAAA,UAAK,EAAC,SAAS,CAAC,CAAC;AA0B3B;;;;;GAKG;AACH,SAAgB,OAAO,CAAC,KAAmB;IACvC,MAAM,EACF,IAAI,GAAG,KAAK,EACZ,YAAY,EACZ,aAAa,EACb,cAAc,GAAG,IAAI,EACrB,KAAK,GAAG,IAAI,EACZ,YAAY,KAEZ,KAAK,EADF,SAAS,kBACZ,KAAK,EARH,oFAQL,CAAQ,CAAC;IACV,MAAM,QAAQ,GAAG,IAAA,iBAAS,GAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,IAAA,iBAAS,GAAE,CAAC;IAC5B,MAAM,EAAC,cAAc,EAAC,GAAG,IAAA,yCAAmB,EAAC,QAAQ,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEjF,gGAAgG;IAChG,+FAA+F;IAC/F,MAAM,UAAU,GAAG,eAAK,CAAC,WAAW,CAAC,CAAC,IAA2B,EAAE,EAAE;QACjE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,YAAY,CAAC,YAAY,EAAE,IAAA,WAAI,EAAC,aAAa,CAAC,CAAC,CAAC;IAC1D,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,eAAe,GAAG,GAAG,EAAE;QACzB,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,KAAK,CAAC,CAAC;IAC1B,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,uBAAC,yBAAW,oBAAK,SAAS,IAAE,WAAW,EAAE,eAAe,IAAI,CAAC;IAE1E,IAAI,QAAQ,EAAE,CAAC;QACX,OAAO,CACH,uBAAC,aAAK,IACF,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,IAAA,WAAI,EAAC,aAAa,CAAC,EAC1B,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,KAAK,CAAC,EACpC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,EACrB,gBAAgB,EAAE,CAAC,CAAC,eAAe,EAAE;gBACjC,eAAe,EAAE,CAAC,cAAc;gBAChC,eAAe,EAAE,cAAc;aAClC,CAAC,EACF,EAAE,EAAC,eAAe,EAClB,wBAAwB,kBAEvB,IAAI,GACD,CACX,CAAC;IACN,CAAC;IAED,OAAO,CACH,uBAAC,aAAK,IACF,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAC,YAAY,EACtB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,UAAU,YAEtB,IAAI,GACD,CACX,CAAC;AACN,CAAC","sourcesContent":["import React from 'react';\n\nimport {Popup, type PopupProps, Sheet, useMobile, useUniqId} from '@gravity-ui/uikit';\n\nimport {useSheetKeyboardFit} from '../../../hooks/useSheetKeyboardFit';\nimport {block} from '../../../utils/cn';\n\nimport {HistoryList, type HistoryListProps} from './HistoryList';\nimport {i18n} from './i18n';\n\nimport './History.scss';\n\nconst b = block('history');\n\n/**\n * Props for the History component\n */\nexport interface HistoryProps extends Omit<HistoryListProps, 'onChatClick'> {\n /** Control popup open state */\n open?: boolean;\n /** Callback when popup open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Anchor element for the popup */\n anchorElement: HTMLElement | null;\n /** Show the mobile sheet title (default: `true`); it stays in `aria-label` either way */\n showSheetTitle?: boolean;\n /**\n * Keep the keyboard focus inside the desktop popup while it is open (default: `true`).\n *\n * The popup is rendered in a portal, so without focus management `Tab` from the trigger\n * button walks through the rest of the page instead of entering the popup, and the chat\n * list cannot be reached from the keyboard at all.\n */\n modal?: boolean;\n /** The element to focus when the desktop popup opens (default: the popup itself) */\n initialFocus?: PopupProps['initialFocus'];\n}\n\n/**\n * History component - wraps HistoryList in a Popup, and in a bottom Sheet in mobile mode\n *\n * @param props - Component props\n * @returns React component\n */\nexport function History(props: HistoryProps) {\n const {\n open = false,\n onOpenChange,\n anchorElement,\n showSheetTitle = true,\n modal = true,\n initialFocus,\n ...listProps\n } = props;\n const isMobile = useMobile();\n const sheetId = useUniqId();\n const {isKeyboardOpen} = useSheetKeyboardFit(isMobile && open, `.${b('sheet')}`);\n\n // `Popup` runs its props through uikit's `filterDOMProps` without the `labelable` option, so an\n // `aria-label` passed to it never reaches the floating element. Set it on the element instead.\n const labelPopup = React.useCallback((node: HTMLDivElement | null) => {\n node?.setAttribute('aria-label', i18n('sheet-title'));\n }, []);\n\n const handleChatClick = () => {\n onOpenChange?.(false);\n };\n\n const list = <HistoryList {...listProps} onChatClick={handleChatClick} />;\n\n if (isMobile) {\n return (\n <Sheet\n id={sheetId}\n title={i18n('sheet-title')}\n visible={open}\n onClose={() => onOpenChange?.(false)}\n className={b('sheet')}\n contentClassName={b('sheet-content', {\n 'without-title': !showSheetTitle,\n 'keyboard-open': isKeyboardOpen,\n })}\n qa=\"history-sheet\"\n allowHideOnContentScroll\n >\n {list}\n </Sheet>\n );\n }\n\n return (\n <Popup\n anchorElement={anchorElement}\n placement=\"bottom-end\"\n open={open}\n onOpenChange={onOpenChange}\n modal={modal}\n initialFocus={initialFocus}\n floatingRef={labelPopup}\n >\n {list}\n </Popup>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":"2.22.0","type":"commonjs","sideEffects":["*.css","*.scss"]}
1
+ {"version":"2.22.1","type":"commonjs","sideEffects":["*.css","*.scss"]}
@@ -113,6 +113,8 @@ import ruLocale from 'dayjs/locale/ru.js';
113
113
  | `filterFunction` | `ChatFilterFunction` | - | `defaultChatFilter` | Custom filter function for search |
114
114
  | `size` | `'s' \| 'm' \| 'l' \| 'xl'` | - | `m`, `xl` on mobile | Size of the list and of the row delete button |
115
115
  | `showSheetTitle` | `boolean` | - | `true` | Show the mobile sheet title (stays in `aria-label`) |
116
+ | `modal` | `boolean` | - | `true` | Keep the keyboard focus inside the desktop popup |
117
+ | `initialFocus` | `PopupProps['initialFocus']` | - | - | Element to focus when the desktop popup opens |
116
118
 
117
119
  Without an explicit `size` the list is `m` on desktop and `xl` in mobile mode, and the row delete
118
120
  button follows it: `s` on desktop, `xl` with a `20px` icon on mobile, so a row keeps a comfortable
@@ -428,7 +430,12 @@ search field stays put while the chat list scrolls under it.
428
430
  - Uses semantic HTML with proper button elements
429
431
  - Keyboard navigation support through Popup and List components
430
432
  - Click areas are properly sized for touch devices
431
- - Focus management handled by underlying UI kit components
433
+ - On desktop the popup is a modal dialog: opening it moves the focus inside, `Tab` and
434
+ `Shift + Tab` cycle through the search field and the chat list, and `Escape` closes the popup and
435
+ returns the focus to the trigger button. Pass `modal={false}` to opt out — the focus then stays on
436
+ the trigger and the popup is only reachable after tabbing through the rest of the page, because it
437
+ is rendered in a portal
438
+ - The popup is labelled with the same "Chat history" string as the mobile sheet
432
439
 
433
440
  ## Internationalization
434
441
 
@@ -1,3 +1,4 @@
1
+ import { type PopupProps } from '@gravity-ui/uikit';
1
2
  import { type HistoryListProps } from "./HistoryList.js";
2
3
  import "./History.css";
3
4
  /**
@@ -12,6 +13,16 @@ export interface HistoryProps extends Omit<HistoryListProps, 'onChatClick'> {
12
13
  anchorElement: HTMLElement | null;
13
14
  /** Show the mobile sheet title (default: `true`); it stays in `aria-label` either way */
14
15
  showSheetTitle?: boolean;
16
+ /**
17
+ * Keep the keyboard focus inside the desktop popup while it is open (default: `true`).
18
+ *
19
+ * The popup is rendered in a portal, so without focus management `Tab` from the trigger
20
+ * button walks through the rest of the page instead of entering the popup, and the chat
21
+ * list cannot be reached from the keyboard at all.
22
+ */
23
+ modal?: boolean;
24
+ /** The element to focus when the desktop popup opens (default: the popup itself) */
25
+ initialFocus?: PopupProps['initialFocus'];
15
26
  }
16
27
  /**
17
28
  * History component - wraps HistoryList in a Popup, and in a bottom Sheet in mobile mode
@@ -1,5 +1,6 @@
1
1
  import { __rest } from "tslib";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
+ import React from 'react';
3
4
  import { Popup, Sheet, useMobile, useUniqId } from '@gravity-ui/uikit';
4
5
  import { useSheetKeyboardFit } from "../../../hooks/useSheetKeyboardFit.js";
5
6
  import { block } from "../../../utils/cn.js";
@@ -14,10 +15,15 @@ const b = block('history');
14
15
  * @returns React component
15
16
  */
16
17
  export function History(props) {
17
- const { open = false, onOpenChange, anchorElement, showSheetTitle = true } = props, listProps = __rest(props, ["open", "onOpenChange", "anchorElement", "showSheetTitle"]);
18
+ const { open = false, onOpenChange, anchorElement, showSheetTitle = true, modal = true, initialFocus } = props, listProps = __rest(props, ["open", "onOpenChange", "anchorElement", "showSheetTitle", "modal", "initialFocus"]);
18
19
  const isMobile = useMobile();
19
20
  const sheetId = useUniqId();
20
21
  const { isKeyboardOpen } = useSheetKeyboardFit(isMobile && open, `.${b('sheet')}`);
22
+ // `Popup` runs its props through uikit's `filterDOMProps` without the `labelable` option, so an
23
+ // `aria-label` passed to it never reaches the floating element. Set it on the element instead.
24
+ const labelPopup = React.useCallback((node) => {
25
+ node === null || node === void 0 ? void 0 : node.setAttribute('aria-label', i18n('sheet-title'));
26
+ }, []);
21
27
  const handleChatClick = () => {
22
28
  onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(false);
23
29
  };
@@ -28,6 +34,6 @@ export function History(props) {
28
34
  'keyboard-open': isKeyboardOpen,
29
35
  }), qa: "history-sheet", allowHideOnContentScroll: true, children: list }));
30
36
  }
31
- return (_jsx(Popup, { anchorElement: anchorElement, placement: "bottom-end", open: open, onOpenChange: onOpenChange, children: list }));
37
+ return (_jsx(Popup, { anchorElement: anchorElement, placement: "bottom-end", open: open, onOpenChange: onOpenChange, modal: modal, initialFocus: initialFocus, floatingRef: labelPopup, children: list }));
32
38
  }
33
39
  //# sourceMappingURL=History.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"History.js","sourceRoot":"../../../../../src","sources":["components/templates/History/History.tsx"],"names":[],"mappings":";;AAAA,OAAO,EAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAErE,OAAO,EAAC,mBAAmB,EAAC,8CAA2C;AACvE,OAAO,EAAC,KAAK,EAAC,6BAA0B;AAExC,OAAO,EAAC,WAAW,EAAwB,yBAAsB;AACjE,OAAO,EAAC,IAAI,EAAC,wBAAe;AAE5B,uBAAwB;AAExB,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;AAgB3B;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,KAAmB;IACvC,MAAM,EAAC,IAAI,GAAG,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,GAAG,IAAI,KAAkB,KAAK,EAAlB,SAAS,UAAI,KAAK,EAAxF,2DAAgF,CAAQ,CAAC;IAC/F,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAC5B,MAAM,EAAC,cAAc,EAAC,GAAG,mBAAmB,CAAC,QAAQ,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEjF,MAAM,eAAe,GAAG,GAAG,EAAE;QACzB,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,KAAK,CAAC,CAAC;IAC1B,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,KAAC,WAAW,oBAAK,SAAS,IAAE,WAAW,EAAE,eAAe,IAAI,CAAC;IAE1E,IAAI,QAAQ,EAAE,CAAC;QACX,OAAO,CACH,KAAC,KAAK,IACF,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,EAC1B,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,KAAK,CAAC,EACpC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,EACrB,gBAAgB,EAAE,CAAC,CAAC,eAAe,EAAE;gBACjC,eAAe,EAAE,CAAC,cAAc;gBAChC,eAAe,EAAE,cAAc;aAClC,CAAC,EACF,EAAE,EAAC,eAAe,EAClB,wBAAwB,kBAEvB,IAAI,GACD,CACX,CAAC;IACN,CAAC;IAED,OAAO,CACH,KAAC,KAAK,IACF,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAC,YAAY,EACtB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,YAAY,YAEzB,IAAI,GACD,CACX,CAAC;AACN,CAAC","sourcesContent":["import {Popup, Sheet, useMobile, useUniqId} from '@gravity-ui/uikit';\n\nimport {useSheetKeyboardFit} from '../../../hooks/useSheetKeyboardFit';\nimport {block} from '../../../utils/cn';\n\nimport {HistoryList, type HistoryListProps} from './HistoryList';\nimport {i18n} from './i18n';\n\nimport './History.scss';\n\nconst b = block('history');\n\n/**\n * Props for the History component\n */\nexport interface HistoryProps extends Omit<HistoryListProps, 'onChatClick'> {\n /** Control popup open state */\n open?: boolean;\n /** Callback when popup open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Anchor element for the popup */\n anchorElement: HTMLElement | null;\n /** Show the mobile sheet title (default: `true`); it stays in `aria-label` either way */\n showSheetTitle?: boolean;\n}\n\n/**\n * History component - wraps HistoryList in a Popup, and in a bottom Sheet in mobile mode\n *\n * @param props - Component props\n * @returns React component\n */\nexport function History(props: HistoryProps) {\n const {open = false, onOpenChange, anchorElement, showSheetTitle = true, ...listProps} = props;\n const isMobile = useMobile();\n const sheetId = useUniqId();\n const {isKeyboardOpen} = useSheetKeyboardFit(isMobile && open, `.${b('sheet')}`);\n\n const handleChatClick = () => {\n onOpenChange?.(false);\n };\n\n const list = <HistoryList {...listProps} onChatClick={handleChatClick} />;\n\n if (isMobile) {\n return (\n <Sheet\n id={sheetId}\n title={i18n('sheet-title')}\n visible={open}\n onClose={() => onOpenChange?.(false)}\n className={b('sheet')}\n contentClassName={b('sheet-content', {\n 'without-title': !showSheetTitle,\n 'keyboard-open': isKeyboardOpen,\n })}\n qa=\"history-sheet\"\n allowHideOnContentScroll\n >\n {list}\n </Sheet>\n );\n }\n\n return (\n <Popup\n anchorElement={anchorElement}\n placement=\"bottom-end\"\n open={open}\n onOpenChange={onOpenChange}\n >\n {list}\n </Popup>\n );\n}\n"]}
1
+ {"version":3,"file":"History.js","sourceRoot":"../../../../../src","sources":["components/templates/History/History.tsx"],"names":[],"mappings":";;AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAC,KAAK,EAAmB,KAAK,EAAE,SAAS,EAAE,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAEtF,OAAO,EAAC,mBAAmB,EAAC,8CAA2C;AACvE,OAAO,EAAC,KAAK,EAAC,6BAA0B;AAExC,OAAO,EAAC,WAAW,EAAwB,yBAAsB;AACjE,OAAO,EAAC,IAAI,EAAC,wBAAe;AAE5B,uBAAwB;AAExB,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;AA0B3B;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,KAAmB;IACvC,MAAM,EACF,IAAI,GAAG,KAAK,EACZ,YAAY,EACZ,aAAa,EACb,cAAc,GAAG,IAAI,EACrB,KAAK,GAAG,IAAI,EACZ,YAAY,KAEZ,KAAK,EADF,SAAS,UACZ,KAAK,EARH,oFAQL,CAAQ,CAAC;IACV,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAC5B,MAAM,EAAC,cAAc,EAAC,GAAG,mBAAmB,CAAC,QAAQ,IAAI,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEjF,gGAAgG;IAChG,+FAA+F;IAC/F,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,IAA2B,EAAE,EAAE;QACjE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,YAAY,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IAC1D,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,eAAe,GAAG,GAAG,EAAE;QACzB,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,KAAK,CAAC,CAAC;IAC1B,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,KAAC,WAAW,oBAAK,SAAS,IAAE,WAAW,EAAE,eAAe,IAAI,CAAC;IAE1E,IAAI,QAAQ,EAAE,CAAC;QACX,OAAO,CACH,KAAC,KAAK,IACF,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,EAC1B,OAAO,EAAE,IAAI,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,KAAK,CAAC,EACpC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,EACrB,gBAAgB,EAAE,CAAC,CAAC,eAAe,EAAE;gBACjC,eAAe,EAAE,CAAC,cAAc;gBAChC,eAAe,EAAE,cAAc;aAClC,CAAC,EACF,EAAE,EAAC,eAAe,EAClB,wBAAwB,kBAEvB,IAAI,GACD,CACX,CAAC;IACN,CAAC;IAED,OAAO,CACH,KAAC,KAAK,IACF,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAC,YAAY,EACtB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,UAAU,YAEtB,IAAI,GACD,CACX,CAAC;AACN,CAAC","sourcesContent":["import React from 'react';\n\nimport {Popup, type PopupProps, Sheet, useMobile, useUniqId} from '@gravity-ui/uikit';\n\nimport {useSheetKeyboardFit} from '../../../hooks/useSheetKeyboardFit';\nimport {block} from '../../../utils/cn';\n\nimport {HistoryList, type HistoryListProps} from './HistoryList';\nimport {i18n} from './i18n';\n\nimport './History.scss';\n\nconst b = block('history');\n\n/**\n * Props for the History component\n */\nexport interface HistoryProps extends Omit<HistoryListProps, 'onChatClick'> {\n /** Control popup open state */\n open?: boolean;\n /** Callback when popup open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Anchor element for the popup */\n anchorElement: HTMLElement | null;\n /** Show the mobile sheet title (default: `true`); it stays in `aria-label` either way */\n showSheetTitle?: boolean;\n /**\n * Keep the keyboard focus inside the desktop popup while it is open (default: `true`).\n *\n * The popup is rendered in a portal, so without focus management `Tab` from the trigger\n * button walks through the rest of the page instead of entering the popup, and the chat\n * list cannot be reached from the keyboard at all.\n */\n modal?: boolean;\n /** The element to focus when the desktop popup opens (default: the popup itself) */\n initialFocus?: PopupProps['initialFocus'];\n}\n\n/**\n * History component - wraps HistoryList in a Popup, and in a bottom Sheet in mobile mode\n *\n * @param props - Component props\n * @returns React component\n */\nexport function History(props: HistoryProps) {\n const {\n open = false,\n onOpenChange,\n anchorElement,\n showSheetTitle = true,\n modal = true,\n initialFocus,\n ...listProps\n } = props;\n const isMobile = useMobile();\n const sheetId = useUniqId();\n const {isKeyboardOpen} = useSheetKeyboardFit(isMobile && open, `.${b('sheet')}`);\n\n // `Popup` runs its props through uikit's `filterDOMProps` without the `labelable` option, so an\n // `aria-label` passed to it never reaches the floating element. Set it on the element instead.\n const labelPopup = React.useCallback((node: HTMLDivElement | null) => {\n node?.setAttribute('aria-label', i18n('sheet-title'));\n }, []);\n\n const handleChatClick = () => {\n onOpenChange?.(false);\n };\n\n const list = <HistoryList {...listProps} onChatClick={handleChatClick} />;\n\n if (isMobile) {\n return (\n <Sheet\n id={sheetId}\n title={i18n('sheet-title')}\n visible={open}\n onClose={() => onOpenChange?.(false)}\n className={b('sheet')}\n contentClassName={b('sheet-content', {\n 'without-title': !showSheetTitle,\n 'keyboard-open': isKeyboardOpen,\n })}\n qa=\"history-sheet\"\n allowHideOnContentScroll\n >\n {list}\n </Sheet>\n );\n }\n\n return (\n <Popup\n anchorElement={anchorElement}\n placement=\"bottom-end\"\n open={open}\n onOpenChange={onOpenChange}\n modal={modal}\n initialFocus={initialFocus}\n floatingRef={labelPopup}\n >\n {list}\n </Popup>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":"2.22.0","type":"module","sideEffects":["*.css","*.scss"]}
1
+ {"version":"2.22.1","type":"module","sideEffects":["*.css","*.scss"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/aikit",
3
- "version": "2.22.0",
3
+ "version": "2.22.1",
4
4
  "description": "Gravity UI base kit for building ai assistant chats",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",