@cloud-ru/ds-accordion 1.0.8-preview-d90ac2be.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +8 -8
  3. package/dist/cjs/Accordion.d.ts +10 -10
  4. package/dist/cjs/components/CollapseBlock/CollapseBlock.d.ts +5 -2
  5. package/dist/cjs/components/CollapseBlock/CollapseBlock.js +7 -2
  6. package/dist/cjs/components/CollapseBlock/hooks.js +1 -10
  7. package/dist/cjs/components/CollapseBlock/styles.module.css +96 -99
  8. package/dist/cjs/helperComponents/ChevronButton/ChevronButton.d.ts +11 -0
  9. package/dist/cjs/helperComponents/ChevronButton/ChevronButton.js +13 -0
  10. package/dist/cjs/helperComponents/ChevronButton/index.d.ts +1 -0
  11. package/dist/cjs/helperComponents/{CollapseChevron → ChevronButton}/index.js +1 -1
  12. package/dist/cjs/helperComponents/ChevronButton/styles.module.css +33 -0
  13. package/dist/cjs/helperComponents/index.d.ts +1 -0
  14. package/dist/cjs/helperComponents/index.js +17 -0
  15. package/dist/cjs/style.css +129 -99
  16. package/dist/esm/Accordion.d.ts +10 -10
  17. package/dist/esm/components/CollapseBlock/CollapseBlock.d.ts +5 -2
  18. package/dist/esm/components/CollapseBlock/CollapseBlock.js +7 -2
  19. package/dist/esm/components/CollapseBlock/hooks.js +1 -10
  20. package/dist/esm/components/CollapseBlock/styles.module.css +96 -99
  21. package/dist/esm/helperComponents/ChevronButton/ChevronButton.d.ts +11 -0
  22. package/dist/esm/helperComponents/ChevronButton/ChevronButton.js +7 -0
  23. package/dist/esm/helperComponents/ChevronButton/index.d.ts +1 -0
  24. package/dist/esm/helperComponents/ChevronButton/index.js +1 -0
  25. package/dist/esm/helperComponents/ChevronButton/styles.module.css +33 -0
  26. package/dist/esm/helperComponents/index.d.ts +1 -0
  27. package/dist/esm/helperComponents/index.js +1 -0
  28. package/dist/esm/style.css +129 -99
  29. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  30. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  31. package/package.json +7 -9
  32. package/src/components/CollapseBlock/CollapseBlock.tsx +25 -12
  33. package/src/components/CollapseBlock/hooks.ts +1 -11
  34. package/src/components/CollapseBlock/styles.module.scss +7 -4
  35. package/src/helperComponents/ChevronButton/ChevronButton.tsx +30 -0
  36. package/src/helperComponents/ChevronButton/index.ts +1 -0
  37. package/src/helperComponents/ChevronButton/styles.module.scss +41 -0
  38. package/src/helperComponents/index.ts +1 -0
  39. package/dist/cjs/helperComponents/CollapseChevron/CollapseChevron.d.ts +0 -6
  40. package/dist/cjs/helperComponents/CollapseChevron/CollapseChevron.js +0 -18
  41. package/dist/cjs/helperComponents/CollapseChevron/index.d.ts +0 -1
  42. package/dist/esm/helperComponents/CollapseChevron/CollapseChevron.d.ts +0 -6
  43. package/dist/esm/helperComponents/CollapseChevron/CollapseChevron.js +0 -12
  44. package/dist/esm/helperComponents/CollapseChevron/index.d.ts +0 -1
  45. package/dist/esm/helperComponents/CollapseChevron/index.js +0 -1
  46. package/src/helperComponents/CollapseChevron/CollapseChevron.tsx +0 -29
  47. package/src/helperComponents/CollapseChevron/index.ts +0 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 1.1.0 (2026-09-25)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **FF-9085:** render accordion demo content as block to drop inherited line box ([a5c3b97](https://github.com/cloud-ru-tech/snack-v2/commit/a5c3b97d195f65f585c38b413fc7afcdbe0b4645))
11
+ - **FF-9085:** restore tertiary body padding and chevron label in accordion ([4dc4eec](https://github.com/cloud-ru-tech/snack-v2/commit/4dc4eecfbc3d0709324a694a8083f647000c445a))
12
+
13
+ ### Features
14
+
15
+ - **FF-9083:** align buttons with Snack UI Kit and extend mobile touch target ([bad5a26](https://github.com/cloud-ru-tech/snack-v2/commit/bad5a268c1d8328a361199b64399fa23380e6da8))
16
+
6
17
  ## 1.0.7 (2026-09-18)
7
18
 
8
19
  ### Bug Fixes
package/README.md CHANGED
@@ -305,7 +305,7 @@ export function NestedLevels() {
305
305
 
306
306
  | Prop | Type | Default | Description |
307
307
  |------|------|---------|-------------|
308
- | `afterTitle` | `ReactNode` | — | Контент справа от заголовка |
308
+ | `afterTitle` | `ReactNode` | — | Контент справа от заголовка. Текст слота входит в доступное имя кнопки-шеврона вместе с `title`, <br/> поэтому без `title` в слот можно передать собственный заголовок. |
309
309
  | `backgroundPredefined` | `"blueBackground"` \| `"decorTransparent"` \| `"greenBackground"` \| `"neutralBackground1Level"` \| `"orangeBackground"` \| `"pinkBackground"` \| `"primaryBackground"` \| `"redBackground"` \| `"transparent"` \| `"violetBackground"` \| `"yellowBackground"` | `neutralBackground1Level` | Слой backgroundPredefined + acrylic (см. `BACKGROUND_PREDEFINED_FILL` в `@cloud-ru/ds-materials`). <br/> По умолчанию `material/neutralBackground1Level`. |
310
310
  | `chevronPosition` | `"after"` \| `"before"` | `after` | Положение шеврона-раскрытия относительно текста (`before` \| `after`) |
311
311
  | `children` | `string \| number \| boolean \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| null \| undefined` | — | |
@@ -316,7 +316,7 @@ export function NestedLevels() {
316
316
  | `keepMounted` | `boolean` | `false` | Оставлять ли контент в DOM при сворачивании |
317
317
  | `showChevron` | `boolean` | `true` | Показывать ли шеврон-раскрытия рядом с заголовком (по умолчанию `true`) |
318
318
  | `subTitle` | `ReactNode` | — | Подзаголовок под строкой заголовка |
319
- | `title` | `string` | — | Начальное состояние раскрытия (uncontrolled) |
319
+ | `title` | `string` | — | Заголовок блока |
320
320
  | `view` | `"elevated"` \| `"outline"` \| `"simple"` | `simple` | Визуальный вариант обложки (`simple`, `outline`, `elevated`) |
321
321
 
322
322
  ##### Related types
@@ -355,7 +355,7 @@ export function AfterTitle() {
355
355
 
356
356
  | Prop | Type | Default | Description |
357
357
  |------|------|---------|-------------|
358
- | `afterTitle` | `ReactNode` | — | Контент справа от заголовка |
358
+ | `afterTitle` | `ReactNode` | — | Контент справа от заголовка. Текст слота входит в доступное имя кнопки-шеврона вместе с `title`, <br/> поэтому без `title` в слот можно передать собственный заголовок. |
359
359
  | `backgroundPredefined` | `"blueBackground"` \| `"decorTransparent"` \| `"greenBackground"` \| `"neutralBackground1Level"` \| `"orangeBackground"` \| `"pinkBackground"` \| `"primaryBackground"` \| `"redBackground"` \| `"transparent"` \| `"violetBackground"` \| `"yellowBackground"` | — | Слой backgroundPredefined + acrylic (см. `BACKGROUND_PREDEFINED_FILL` в `@cloud-ru/ds-materials`). <br/> По умолчанию `material/neutralBackground1Level`. |
360
360
  | `chevronPosition` | `"after"` \| `"before"` | — | Положение шеврона-раскрытия относительно текста (`before` \| `after`) |
361
361
  | `children` | `string \| number \| boolean \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| null \| undefined` | — | |
@@ -365,7 +365,7 @@ export function AfterTitle() {
365
365
  | `keepMounted` | `boolean` | — | Оставлять ли контент в DOM при сворачивании |
366
366
  | `showChevron` | `boolean` | — | Показывать ли шеврон-раскрытия рядом с заголовком (по умолчанию `true`) |
367
367
  | `subTitle` | `ReactNode` | — | Подзаголовок под строкой заголовка |
368
- | `title` | `string` | — | Начальное состояние раскрытия (uncontrolled) |
368
+ | `title` | `string` | — | Заголовок блока |
369
369
  | `view` | `"elevated"` \| `"outline"` \| `"simple"` | — | Визуальный вариант обложки (`simple`, `outline`, `elevated`) |
370
370
 
371
371
  #### Related types
@@ -412,7 +412,7 @@ export function ChevronBefore() {
412
412
 
413
413
  | Prop | Type | Default | Description |
414
414
  |------|------|---------|-------------|
415
- | `afterTitle` | `ReactNode` | — | Контент справа от заголовка |
415
+ | `afterTitle` | `ReactNode` | — | Контент справа от заголовка. Текст слота входит в доступное имя кнопки-шеврона вместе с `title`, <br/> поэтому без `title` в слот можно передать собственный заголовок. |
416
416
  | `backgroundPredefined` | `"blueBackground"` \| `"decorTransparent"` \| `"greenBackground"` \| `"neutralBackground1Level"` \| `"orangeBackground"` \| `"pinkBackground"` \| `"primaryBackground"` \| `"redBackground"` \| `"transparent"` \| `"violetBackground"` \| `"yellowBackground"` | — | Слой backgroundPredefined + acrylic (см. `BACKGROUND_PREDEFINED_FILL` в `@cloud-ru/ds-materials`). <br/> По умолчанию `material/neutralBackground1Level`. |
417
417
  | `chevronPosition` | `"after"` \| `"before"` | — | Положение шеврона-раскрытия относительно текста (`before` \| `after`) |
418
418
  | `children` | `string \| number \| boolean \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| null \| undefined` | — | |
@@ -422,7 +422,7 @@ export function ChevronBefore() {
422
422
  | `keepMounted` | `boolean` | — | Оставлять ли контент в DOM при сворачивании |
423
423
  | `showChevron` | `boolean` | — | Показывать ли шеврон-раскрытия рядом с заголовком (по умолчанию `true`) |
424
424
  | `subTitle` | `ReactNode` | — | Подзаголовок под строкой заголовка |
425
- | `title` | `string` | — | Начальное состояние раскрытия (uncontrolled) |
425
+ | `title` | `string` | — | Заголовок блока |
426
426
  | `view` | `"elevated"` \| `"outline"` \| `"simple"` | — | Визуальный вариант обложки (`simple`, `outline`, `elevated`) |
427
427
 
428
428
  #### Related types
@@ -468,7 +468,7 @@ export function NestedLevels() {
468
468
 
469
469
  | Prop | Type | Default | Description |
470
470
  |------|------|---------|-------------|
471
- | `afterTitle` | `ReactNode` | — | Контент справа от заголовка |
471
+ | `afterTitle` | `ReactNode` | — | Контент справа от заголовка. Текст слота входит в доступное имя кнопки-шеврона вместе с `title`, <br/> поэтому без `title` в слот можно передать собственный заголовок. |
472
472
  | `chevronPosition` | `"after"` \| `"before"` | — | Положение шеврона-раскрытия относительно текста (`before` \| `after`) |
473
473
  | `children` | `string \| number \| boolean \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| null \| undefined` | — | |
474
474
  | `className` | `string` | — | Дополнительный класс корневого элемента |
@@ -477,7 +477,7 @@ export function NestedLevels() {
477
477
  | `keepMounted` | `boolean` | — | Оставлять ли контент в DOM при сворачивании |
478
478
  | `showChevron` | `boolean` | — | Показывать ли шеврон-раскрытия рядом с заголовком (по умолчанию `true`) |
479
479
  | `subTitle` | `ReactNode` | — | Подзаголовок под строкой заголовка |
480
- | `title` | `string` | — | Начальное состояние раскрытия (uncontrolled) |
480
+ | `title` | `string` | — | Заголовок блока |
481
481
 
482
482
  #### Related types
483
483
 
@@ -22,9 +22,10 @@ export type AccordionProps = PropsWithChildren<{
22
22
  declare function AccordionBase({ selectionMode, onExpandedChange, expandedDefault, expanded, children, }: AccordionProps): import("react/jsx-runtime").JSX.Element;
23
23
  export declare const Accordion: typeof AccordionBase & {
24
24
  CollapseBlockPrimary: (props: {
25
- className?: string | undefined;
26
- children?: import("react").ReactNode;
27
25
  'data-test-id'?: string | undefined;
26
+ children?: import("react").ReactNode;
27
+ className?: string | undefined;
28
+ id: string;
28
29
  "aria-activedescendant"?: string | undefined | undefined;
29
30
  "aria-atomic"?: (boolean | "true" | "false") | undefined;
30
31
  "aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined | undefined;
@@ -78,20 +79,20 @@ export declare const Accordion: typeof AccordionBase & {
78
79
  "aria-valuemin"?: number | undefined | undefined;
79
80
  "aria-valuenow"?: number | undefined | undefined;
80
81
  "aria-valuetext"?: string | undefined | undefined;
81
- view?: import("./types").View | undefined;
82
- title?: string | undefined;
83
- id: string;
84
82
  keepMounted?: boolean | undefined;
83
+ title?: string | undefined;
85
84
  afterTitle?: import("react").ReactNode;
86
85
  subTitle?: import("react").ReactNode;
86
+ view?: import("./types").View | undefined;
87
87
  chevronPosition?: import("./types").ChevronPosition | undefined;
88
88
  backgroundPredefined?: import("@cloud-ru/ds-materials").BackgroundPredefinedFill | undefined;
89
89
  showChevron?: boolean | undefined;
90
90
  }) => import("react/jsx-runtime").JSX.Element;
91
91
  CollapseBlockSecondary: (props: {
92
- className?: string | undefined;
93
- children?: import("react").ReactNode;
94
92
  'data-test-id'?: string | undefined;
93
+ children?: import("react").ReactNode;
94
+ className?: string | undefined;
95
+ id: string;
95
96
  "aria-activedescendant"?: string | undefined | undefined;
96
97
  "aria-atomic"?: (boolean | "true" | "false") | undefined;
97
98
  "aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined | undefined;
@@ -145,12 +146,11 @@ export declare const Accordion: typeof AccordionBase & {
145
146
  "aria-valuemin"?: number | undefined | undefined;
146
147
  "aria-valuenow"?: number | undefined | undefined;
147
148
  "aria-valuetext"?: string | undefined | undefined;
148
- view?: import("./types").View | undefined;
149
- title?: string | undefined;
150
- id: string;
151
149
  keepMounted?: boolean | undefined;
150
+ title?: string | undefined;
152
151
  afterTitle?: import("react").ReactNode;
153
152
  subTitle?: import("react").ReactNode;
153
+ view?: import("./types").View | undefined;
154
154
  chevronPosition?: import("./types").ChevronPosition | undefined;
155
155
  backgroundPredefined?: import("@cloud-ru/ds-materials").BackgroundPredefinedFill | undefined;
156
156
  showChevron?: boolean | undefined;
@@ -6,9 +6,12 @@ type Component = 'accordionPrimary' | 'accordionSecondary' | 'accordionTertiary'
6
6
  export type CollapseBlockProps = PropsWithChildren<WithSupportProps<{
7
7
  /** Уникальный идентификатор блока в группе переключателей */
8
8
  id: string;
9
- /** Начальное состояние раскрытия (uncontrolled) */
9
+ /** Заголовок блока */
10
10
  title?: string;
11
- /** Контент справа от заголовка */
11
+ /**
12
+ * Контент справа от заголовка. Текст слота входит в доступное имя кнопки-шеврона вместе с `title`,
13
+ * поэтому без `title` в слот можно передать собственный заголовок.
14
+ */
12
15
  afterTitle?: ReactNode;
13
16
  /** Подзаголовок под строкой заголовка */
14
17
  subTitle?: ReactNode;
@@ -11,8 +11,9 @@ const truncate_string_1 = require("@cloud-ru/ds-truncate-string");
11
11
  const typography_1 = require("@cloud-ru/ds-typography");
12
12
  const utils_1 = require("@cloud-ru/ds-utils");
13
13
  const classnames_1 = __importDefault(require("classnames"));
14
+ const react_1 = require("react");
14
15
  const constants_1 = require("../../constants");
15
- const CollapseChevron_1 = require("../../helperComponents/CollapseChevron");
16
+ const helperComponents_1 = require("../../helperComponents");
16
17
  const hooks_1 = require("./hooks");
17
18
  const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
18
19
  const MAP_COMPONENT_TO_TILE_SIZE = {
@@ -29,9 +30,13 @@ function CollapseBlock({ id, title, afterTitle, subTitle, children, className, v
29
30
  keepMounted,
30
31
  });
31
32
  const { appearance, level } = (0, materials_1.backgroundPredefinedFillToAcrylic)(backgroundPredefined);
33
+ const titleId = (0, react_1.useId)();
34
+ const afterTitleId = (0, react_1.useId)();
35
+ const contentId = (0, react_1.useId)();
36
+ const chevronLabelledBy = [title && titleId, afterTitle && afterTitleId].filter(Boolean).join(' ') || undefined;
32
37
  return ((0, jsx_runtime_1.jsxs)("div", { ...(0, utils_1.extractSupportProps)(rest), className: (0, classnames_1.default)(styles_module_scss_1.default.wrapper, className), "data-acrylic-appearance": appearance, "data-acrylic-level": level, "data-expanded": isOpen, "data-completely-open": isCompletelyOpen || undefined, "data-view": view, "data-component": component, "data-test-id": dataTestId ?? constants_1.TEST_IDS.collapseBlock, style: {
33
38
  '--sn-collapse-block-animation-duration': `${constants_1.ANIMATION_DURATION}ms`,
34
- }, children: [component !== 'accordionTertiary' && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.acrylic }), view === constants_1.VIEW.Outline && (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.stateLayer, "data-state": 'borderOnBackground' })] })), (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.titleContent, "data-expanded": isOpen || undefined, "data-completely-close": isCompletelyClose || undefined, "data-chevron-position": chevronPosition, onClick: toggleOpen, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.titleWrapper, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.titleLine, children: [title && ((0, jsx_runtime_1.jsx)(typography_1.Typography, { size: MAP_COMPONENT_TO_TILE_SIZE[component], variant: 'title', className: styles_module_scss_1.default.title, "data-test-id": constants_1.TEST_IDS.title, children: (0, jsx_runtime_1.jsx)(truncate_string_1.TruncateString, { text: title, variant: 'end' }) })), afterTitle && ((0, jsx_runtime_1.jsx)("div", { "data-test-id": constants_1.TEST_IDS.afterTitle, className: styles_module_scss_1.default.afterTitle, children: afterTitle }))] }), subTitle && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.subTitle, "data-test-id": constants_1.TEST_IDS.subTitle, children: subTitle }))] }), showChevron && (0, jsx_runtime_1.jsx)(CollapseChevron_1.CollapseChevron, { isOpen: isOpen, className: styles_module_scss_1.default.chevronWrapper })] }), (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.collapse, "data-expanded": isOpen || undefined, "aria-hidden": !isOpen, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(styles_module_scss_1.default.container, isCompletelyOpen && styles_module_scss_1.default.containerCompletelyOpen), "data-completely-close": isCompletelyClose || undefined, "data-expanded": isOpen || undefined, children: [(0, jsx_runtime_1.jsx)("div", {}), isMounted ? ((0, jsx_runtime_1.jsx)("div", { "data-test-id": constants_1.TEST_IDS.content, className: styles_module_scss_1.default.content, children: children })) : null] }) })] }));
39
+ }, children: [component !== 'accordionTertiary' && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.acrylic }), view === constants_1.VIEW.Outline && (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.stateLayer, "data-state": 'borderOnBackground' })] })), (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.titleContent, "data-expanded": isOpen || undefined, "data-completely-close": isCompletelyClose || undefined, "data-chevron-position": chevronPosition, onClick: toggleOpen, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.titleWrapper, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.titleLine, children: [title && ((0, jsx_runtime_1.jsx)(typography_1.Typography, { size: MAP_COMPONENT_TO_TILE_SIZE[component], variant: 'title', className: styles_module_scss_1.default.title, id: titleId, "data-test-id": constants_1.TEST_IDS.title, children: (0, jsx_runtime_1.jsx)(truncate_string_1.TruncateString, { text: title, variant: 'end' }) })), afterTitle && ((0, jsx_runtime_1.jsx)("div", { id: afterTitleId, "data-test-id": constants_1.TEST_IDS.afterTitle, className: styles_module_scss_1.default.afterTitle, children: afterTitle }))] }), subTitle && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.subTitle, "data-test-id": constants_1.TEST_IDS.subTitle, children: subTitle }))] }), showChevron && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.chevronWrapper, children: (0, jsx_runtime_1.jsx)(helperComponents_1.ChevronButton, { expanded: isOpen, contentId: contentId, labelledBy: chevronLabelledBy, "data-test-id": constants_1.TEST_IDS.chevron }) }))] }), (0, jsx_runtime_1.jsx)("div", { id: contentId, className: styles_module_scss_1.default.collapse, "data-expanded": isOpen || undefined, "aria-hidden": !isOpen, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(styles_module_scss_1.default.container, isCompletelyOpen && styles_module_scss_1.default.containerCompletelyOpen), "data-completely-close": isCompletelyClose || undefined, "data-expanded": isOpen || undefined, children: [(0, jsx_runtime_1.jsx)("div", {}), isMounted ? (0, jsx_runtime_1.jsx)("div", { "data-test-id": constants_1.TEST_IDS.content, children: children }) : null] }) })] }));
35
40
  }
36
41
  function getCollapseBlock(component) {
37
42
  return function CollapseBlockWithComponent(props) {
@@ -9,21 +9,12 @@ function useCollapseState({ id, keepMounted = false }) {
9
9
  // Контент доживает до конца закрывающей анимации, но при открытии появляется синхронно с
10
10
  // `isOpen` — если монтировать его эффектом, первый кадр раскрытия считается по пустому телу
11
11
  // и высота стартует рывком.
12
- // Стартует с `isOpen`: у раскрытого при маунте блока контент уже смонтирован, и эффект не должен
13
- // добавлять лишний рендер, переключая флаг.
14
- const [keepMountedWhileClosing, setKeepMountedWhileClosing] = (0, react_1.useState)(isOpen);
12
+ const [keepMountedWhileClosing, setKeepMountedWhileClosing] = (0, react_1.useState)(false);
15
13
  const isMounted = isOpen || keepMounted || keepMountedWhileClosing;
16
14
  const [isCompletelyOpen, setIsCompletelyOpen] = (0, react_1.useState)(isOpen);
17
15
  const [isCompletelyClose, setIsCompletelyClose] = (0, react_1.useState)(!isOpen);
18
16
  const timeoutRef = (0, react_1.useRef)(null);
19
- const isFirstRunRef = (0, react_1.useRef)(true);
20
17
  (0, react_1.useEffect)(() => {
21
- // Начальные флаги уже согласованы с `isOpen`, анимировать нечего: без этого каждый блок при
22
- // маунте ставил таймер на `ANIMATION_DURATION` ради setState с тем же значением.
23
- if (isFirstRunRef.current) {
24
- isFirstRunRef.current = false;
25
- return;
26
- }
27
18
  if (isOpen) {
28
19
  setKeepMountedWhileClosing(true);
29
20
  setIsCompletelyClose(false);