@rescui/collapse 0.8.4 → 0.8.5

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,15 +1,15 @@
1
1
  var styles = {
2
- "icon": "_icon_3sp1p2_4",
3
- "sizeXS": "_sizeXS_3sp1p2_14",
4
- "sizeS": "_sizeS_3sp1p2_18",
5
- "sizeM": "_sizeM_3sp1p2_22",
6
- "sizeL": "_sizeL_3sp1p2_26",
7
- "light": "_light_3sp1p2_30",
8
- "dark": "_dark_3sp1p2_34",
9
- "allVariants": "_allVariants_3sp1p2_48",
10
- "variant16": "_variant16_3sp1p2_53",
11
- "variant20": "_variant20_3sp1p2_54",
12
- "variant24": "_variant24_3sp1p2_55",
13
- "variant28": "_variant28_3sp1p2_58"
2
+ "icon": "_icon_1npbgia_4",
3
+ "sizeXS": "_sizeXS_1npbgia_14",
4
+ "sizeS": "_sizeS_1npbgia_18",
5
+ "sizeM": "_sizeM_1npbgia_22",
6
+ "sizeL": "_sizeL_1npbgia_26",
7
+ "light": "_light_1npbgia_30",
8
+ "dark": "_dark_1npbgia_34",
9
+ "allVariants": "_allVariants_1npbgia_48",
10
+ "variant16": "_variant16_1npbgia_53",
11
+ "variant20": "_variant20_1npbgia_54",
12
+ "variant24": "_variant24_1npbgia_55",
13
+ "variant28": "_variant28_1npbgia_58"
14
14
  };
15
15
  export { styles as default };
package/lib/collapse.js CHANGED
@@ -1,19 +1,14 @@
1
1
  "use client";
2
- import React, { useRef, useContext, useState, useEffect } from 'react';
2
+ import React, { useState, useContext, useRef, useEffect } from 'react';
3
3
  import cn from 'classnames';
4
4
  import PropTypes from 'prop-types';
5
5
  import { useThemeWithUndefined } from '@rescui/ui-contexts';
6
- import { useResizeObserver } from '@rescui/use-resize-observer';
7
6
  import RightIcon from './_virtual/right.js';
8
7
  import PlusIcon from './_virtual/plus.js';
9
8
  import { collapseContext } from './context.js';
10
- import { useCollapseState, COLLAPSE_STATES, useStartedClosing } from './use-collapse-state.js';
9
+ import { useCollapseState, COLLAPSE_STATES } from './use-collapse-state.js';
10
+ import { useSafeId } from './use-safe-id.js';
11
11
  import styles from './collapse.p.module.css.js';
12
-
13
- function getRandId() {
14
- return Math.random().toString(36).substring(7);
15
- }
16
-
17
12
  const THEME_STYLES = {
18
13
  light: styles.themeLight,
19
14
  dark: styles.themeDark
@@ -50,10 +45,9 @@ const Collapse = /*#__PURE__*/React.forwardRef( // eslint-disable-next-line comp
50
45
  itemKey,
51
46
  ...restProps
52
47
  } = _ref;
53
- // using the trick from https://github.com/Yaska/react-use-id-hook/
54
- const {
55
- current: key
56
- } = useRef(itemKey ?? getRandId());
48
+ const uniqueId = useSafeId();
49
+ const [key] = useState(() => itemKey ?? uniqueId);
50
+ const [isAccordionConnected, setIsAccordionConnected] = useState(false);
57
51
  const theme = useThemeWithUndefined(themeFromProps);
58
52
  const {
59
53
  openedKey,
@@ -73,34 +67,45 @@ const Collapse = /*#__PURE__*/React.forwardRef( // eslint-disable-next-line comp
73
67
  const icon = iconFromProps ?? iconFromContext ?? 'left-plus';
74
68
  const borderBottom = borderBottomFromProps ?? borderBottomFromContext ?? false;
75
69
  const disableLeftPadding = disableLeftPaddingFromProps ?? disableLeftPaddingFromContext ?? false;
76
- const openedClassName = openedClassnameFromProps ?? openedClassNameFromContext; // height calculations
77
-
78
- const resizeRef = useRef(null);
79
- const [height, setHeight] = useState('initial');
80
- useResizeObserver(resizeRef, entry => setHeight(entry.target.offsetHeight));
81
- const isHeightCalculated = height !== 'initial'; // this state is ignored in accordion
70
+ const openedClassName = openedClassnameFromProps ?? openedClassNameFromContext;
71
+ const contentRef = useRef(null);
72
+ const [isAnimationEnabled, setIsAnimationEnabled] = useState(!isInAccordion); // this state is ignored in accordion
82
73
 
83
74
  const [shouldBeOpenedLocal, setShouldBeOpenedLocal] = useState(isDefaultOpened); // boolean state. ignores CLOSING and OPENING states
84
75
 
85
- const shouldBeOpened = isInAccordion ? openedKey === key : shouldBeOpenedLocal; // add CLOSING and OPENING states.
76
+ const shouldBeOpened = isAccordionConnected ? openedKey === key : shouldBeOpenedLocal;
77
+ useEffect(() => {
78
+ if (!isInAccordion) {
79
+ return;
80
+ }
86
81
 
87
- const {
88
- onAnimationEnd: handleTransitionEnd,
89
- state: collapseState
90
- } = useCollapseState({
82
+ if (!isAccordionConnected) {
83
+ // For an uncontrolled accordion, register the initially opened item.
84
+ // Keep using the local state until this update and the connection update
85
+ // have rendered together.
86
+ if (!isInControlledAccordion && isDefaultOpened && setActiveKey) {
87
+ setActiveKey(key);
88
+ } // eslint-disable-next-line react-hooks/set-state-in-effect
89
+
90
+
91
+ setIsAccordionConnected(true);
92
+ return;
93
+ } // The first accordion state has already been committed. Enabling
94
+ // transitions separately makes its initial reconciliation instantaneous.
95
+ // eslint-disable-next-line react-hooks/set-state-in-effect
96
+
97
+
98
+ setIsAnimationEnabled(true);
99
+ }, [isAccordionConnected, isInAccordion, isInControlledAccordion, isDefaultOpened, setActiveKey, key]); // add CLOSING and OPENING states
100
+
101
+ const collapseState = useCollapseState({
91
102
  shouldBeOpened,
92
- // because how css transitions work, we shouldn't use OPENING and CLOSING states while height still calculating
93
- // it also allows us to skip animation on the first renders
94
- cancelAnimation: !isHeightCalculated
103
+ contentRef
95
104
  });
96
105
  const isOpening = collapseState === COLLAPSE_STATES.OPENING;
97
106
  const isOpened = collapseState === COLLAPSE_STATES.OPEN;
98
107
  const isClosing = collapseState === COLLAPSE_STATES.CLOSING;
99
108
  const isClosed = collapseState === COLLAPSE_STATES.CLOSE;
100
- const {
101
- isStartedClosing,
102
- contentRef
103
- } = useStartedClosing(collapseState);
104
109
  const isRightIcon = icon === 'right-plus';
105
110
  const Icon = icon === 'arrow' ? RightIcon : PlusIcon;
106
111
 
@@ -113,16 +118,10 @@ const Collapse = /*#__PURE__*/React.forwardRef( // eslint-disable-next-line comp
113
118
  setShouldBeOpenedLocal(!shouldBeOpened);
114
119
  };
115
120
 
116
- useEffect(() => {
117
- // for uncontrolled accordion, tell it that this collapse is opened by default
118
- if (isInAccordion && !isInControlledAccordion && isDefaultOpened && setActiveKey) {
119
- setActiveKey(key);
120
- }
121
- }, []);
122
121
  return /*#__PURE__*/React.createElement("div", {
123
122
  "data-test": 'collapse',
124
123
  ...restProps,
125
- className: cn(className, styles.main, isOpening && styles.opening, isOpened && styles.opened, isClosing && !isStartedClosing && styles.closingTransition, isClosing && styles.closing, isClosed && styles.closed, !isClosed && openedClassName, SIZE_STYLES[size], MODE_STYLES[mode], ICON_STYLES[icon], borderBottom && styles.hasBorderBottom, disableLeftPadding && styles.disableLeftPadding, isRightIcon ? styles.rightIcon : styles.leftIcon, THEME_STYLES[theme]),
124
+ className: cn(className, styles.main, isAnimationEnabled && styles.animationEnabled, isOpening && styles.opening, isOpened && styles.opened, isClosing && styles.closing, isClosed && styles.closed, !isClosed && openedClassName, SIZE_STYLES[size], MODE_STYLES[mode], ICON_STYLES[icon], borderBottom && styles.hasBorderBottom, disableLeftPadding && styles.disableLeftPadding, isRightIcon ? styles.rightIcon : styles.leftIcon, THEME_STYLES[theme]),
126
125
  "data-rs-internal": "collapse__collapse",
127
126
  ref: ref
128
127
  }, /*#__PURE__*/React.createElement("button", {
@@ -140,18 +139,9 @@ const Collapse = /*#__PURE__*/React.forwardRef( // eslint-disable-next-line comp
140
139
  }, title)), /*#__PURE__*/React.createElement("div", {
141
140
  className: styles.content,
142
141
  "data-rs-internal": "collapse__content",
143
- style: {
144
- // So, we set the height value only on OPENING stage and just after beginning CLOSING stage
145
- // The reason we don't leave this style for OPEN stage is because some content of the expanded Collapse may change its height dynamically
146
- // This will be processed by resizeObserver, but some devices may lag behind
147
- // And to make collapsing transition work, we need to have a frame with numbered height value before starting the collapse transition
148
- height: isOpening || isStartedClosing ? height : null
149
- },
150
142
  ref: contentRef,
151
- onTransitionEnd: handleTransitionEnd,
152
143
  tabIndex: -1
153
144
  }, /*#__PURE__*/React.createElement("div", {
154
- ref: resizeRef,
155
145
  className: styles.innerWrapper
156
146
  }, children)));
157
147
  });
@@ -1,35 +1,35 @@
1
1
  var styles = {
2
- "themeLight": "_themeLight_1fi1hk_6",
3
- "themeDark": "_themeDark_1fi1hk_9",
4
- "sizeS": "_sizeS_1fi1hk_13",
5
- "sizeM": "_sizeM_1fi1hk_16",
6
- "sizeL": "_sizeL_1fi1hk_19",
7
- "classic": "_classic_1fi1hk_23",
8
- "rock": "_rock_1fi1hk_26",
9
- "clear": "_clear_1fi1hk_29",
10
- "hasBorderBottom": "_hasBorderBottom_1fi1hk_33",
11
- "leftIcon": "_leftIcon_1fi1hk_37",
12
- "rightIcon": "_rightIcon_1fi1hk_40",
13
- "disableLeftPadding": "_disableLeftPadding_1fi1hk_44",
14
- "main": "_main_1fi1hk_48",
15
- "opening": "_opening_1fi1hk_59",
16
- "opened": "_opened_1fi1hk_60",
17
- "closing": "_closing_1fi1hk_61",
18
- "title": "_title_1fi1hk_95",
19
- "content": "_content_1fi1hk_103",
20
- "closed": "_closed_1fi1hk_111",
21
- "closingTransition": "_closingTransition_1fi1hk_120",
22
- "innerWrapper": "_innerWrapper_1fi1hk_127",
23
- "button": "_button_1fi1hk_133",
24
- "icon": "_icon_1fi1hk_186",
25
- "iconPlus": "_iconPlus_1fi1hk_202",
26
- "iconArrow": "_iconArrow_1fi1hk_207",
27
- "accordion": "_accordion_1fi1hk_213",
28
- "accordionGap0": "_accordionGap0_1fi1hk_218",
29
- "accordionGap8": "_accordionGap8_1fi1hk_221",
30
- "accordionGap12": "_accordionGap12_1fi1hk_224",
31
- "accordionGap16": "_accordionGap16_1fi1hk_227",
32
- "accordionGap24": "_accordionGap24_1fi1hk_230",
33
- "accordionGap32": "_accordionGap32_1fi1hk_233"
2
+ "themeLight": "_themeLight_1n76usd_6",
3
+ "themeDark": "_themeDark_1n76usd_9",
4
+ "sizeS": "_sizeS_1n76usd_13",
5
+ "sizeM": "_sizeM_1n76usd_16",
6
+ "sizeL": "_sizeL_1n76usd_19",
7
+ "classic": "_classic_1n76usd_23",
8
+ "rock": "_rock_1n76usd_26",
9
+ "clear": "_clear_1n76usd_29",
10
+ "hasBorderBottom": "_hasBorderBottom_1n76usd_33",
11
+ "leftIcon": "_leftIcon_1n76usd_37",
12
+ "rightIcon": "_rightIcon_1n76usd_40",
13
+ "disableLeftPadding": "_disableLeftPadding_1n76usd_44",
14
+ "main": "_main_1n76usd_48",
15
+ "opening": "_opening_1n76usd_59",
16
+ "opened": "_opened_1n76usd_60",
17
+ "closing": "_closing_1n76usd_61",
18
+ "title": "_title_1n76usd_95",
19
+ "content": "_content_1n76usd_103",
20
+ "animationEnabled": "_animationEnabled_1n76usd_115",
21
+ "closed": "_closed_1n76usd_128",
22
+ "innerWrapper": "_innerWrapper_1n76usd_133",
23
+ "button": "_button_1n76usd_140",
24
+ "icon": "_icon_1n76usd_196",
25
+ "iconPlus": "_iconPlus_1n76usd_217",
26
+ "iconArrow": "_iconArrow_1n76usd_222",
27
+ "accordion": "_accordion_1n76usd_228",
28
+ "accordionGap0": "_accordionGap0_1n76usd_233",
29
+ "accordionGap8": "_accordionGap8_1n76usd_236",
30
+ "accordionGap12": "_accordionGap12_1n76usd_239",
31
+ "accordionGap16": "_accordionGap16_1n76usd_242",
32
+ "accordionGap24": "_accordionGap24_1n76usd_245",
33
+ "accordionGap32": "_accordionGap32_1n76usd_248"
34
34
  };
35
35
  export { styles as default };
package/lib/index.css CHANGED
@@ -1,4 +1,9 @@
1
- ._icon_3sp1p2_4{
1
+ @property --_rs-theme-dark-coefficient{
2
+ syntax:'<number>';
3
+ inherits:true;
4
+ initial-value:0;
5
+ }
6
+ ._icon_1npbgia_4{
2
7
  --_rs-theme-dark:var(
3
8
  --_rs-internal-force-theme-dark-consult-rescui-before-using,
4
9
  var(--rs-theme-dark, 0)
@@ -8,7 +13,7 @@
8
13
  --_rs-theme-light-coefficient:calc(1 - var(--_rs-theme-dark-coefficient));
9
14
  }
10
15
  @supports (color: color-mix(in srgb, #fff 50%, #000 50%)){
11
- ._icon_3sp1p2_4{
16
+ ._icon_1npbgia_4{
12
17
  --_rs-color-primary:color-mix(in srgb, var(--rs-color-primary-light-theme, #6B57FF) calc(100%*var(--_rs-theme-light-coefficient, 1)), var(--rs-color-primary-dark-theme, #8473FF) calc(100%*var(--_rs-theme-dark-coefficient, 0)));
13
18
  --_rs-color-primary-dim:color-mix(in srgb, var(--rs-color-primary-dim-light-theme, #8979ff) calc(100%*var(--_rs-theme-light-coefficient, 1)), var(--rs-color-primary-dim-dark-theme, #6f61d2) calc(100%*var(--_rs-theme-dark-coefficient, 0)));
14
19
  --_rs-color-primary-fog:color-mix(in srgb, var(--rs-color-primary-fog-light-theme, #e1ddff) calc(100%*var(--_rs-theme-light-coefficient, 1)), var(--rs-color-primary-fog-dark-theme, #2e2b49) calc(100%*var(--_rs-theme-dark-coefficient, 0)));
@@ -17,7 +22,7 @@
17
22
  }
18
23
  }
19
24
  @supports not (color: color-mix(in srgb, #fff 50%, #000 50%)){
20
- ._icon_3sp1p2_4{
25
+ ._icon_1npbgia_4{
21
26
  --_rs-color-primary:rgb(calc(var(--_rs-theme-light-coefficient, 1)*107 + var(--_rs-theme-dark-coefficient, 0)*132), calc(var(--_rs-theme-light-coefficient, 1)*87 + var(--_rs-theme-dark-coefficient, 0)*115), 255);
22
27
  --_rs-color-primary-dim:rgb(calc(var(--_rs-theme-light-coefficient, 1)*137 + var(--_rs-theme-dark-coefficient, 0)*111), calc(var(--_rs-theme-light-coefficient, 1)*121 + var(--_rs-theme-dark-coefficient, 0)*97), calc(var(--_rs-theme-light-coefficient, 1)*255 + var(--_rs-theme-dark-coefficient, 0)*210));
23
28
  --_rs-color-primary-fog:rgb(calc(var(--_rs-theme-light-coefficient, 1)*225 + var(--_rs-theme-dark-coefficient, 0)*46), calc(var(--_rs-theme-light-coefficient, 1)*221 + var(--_rs-theme-dark-coefficient, 0)*43), calc(var(--_rs-theme-light-coefficient, 1)*255 + var(--_rs-theme-dark-coefficient, 0)*73));
@@ -25,30 +30,30 @@
25
30
  --_rs-color-primary-t-fog:rgba(calc(var(--_rs-theme-light-coefficient, 1)*107 + var(--_rs-theme-dark-coefficient, 0)*132), calc(var(--_rs-theme-light-coefficient, 1)*87 + var(--_rs-theme-dark-coefficient, 0)*115), 255, calc(var(--_rs-theme-light-coefficient, 1)*0.2 + var(--_rs-theme-dark-coefficient, 0)*0.3));
26
31
  }
27
32
  }
28
- ._icon_3sp1p2_4{
33
+ ._icon_1npbgia_4{
29
34
 
30
35
  fill:var(--_rs-icons-themed-fill-or-initial, currentcolor);
31
36
 
32
37
  width:var(--rs-icons-width, auto);
33
38
  height:var(--rs-icons-height, var(--_rs-icons-height));
34
39
  }
35
- ._sizeXS_3sp1p2_14{
40
+ ._sizeXS_1npbgia_14{
36
41
  --_rs-icons-height:16px;
37
42
  }
38
- ._sizeS_3sp1p2_18{
43
+ ._sizeS_1npbgia_18{
39
44
  --_rs-icons-height:20px;
40
45
  }
41
- ._sizeM_3sp1p2_22{
46
+ ._sizeM_1npbgia_22{
42
47
  --_rs-icons-height:24px;
43
48
  }
44
- ._sizeL_3sp1p2_26{
49
+ ._sizeL_1npbgia_26{
45
50
  --_rs-icons-height:28px;
46
51
  }
47
- ._light_3sp1p2_30{
52
+ ._light_1npbgia_30{
48
53
  --rs-theme-dark:0;
49
54
  --_rs-icons-themed-fill-or-initial:rgb(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227));
50
55
  }
51
- ._dark_3sp1p2_34{
56
+ ._dark_1npbgia_34{
52
57
  --rs-theme-dark:1;
53
58
  --_rs-icons-themed-fill-or-initial:rgb(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227));
54
59
  }
@@ -60,54 +65,59 @@
60
65
  transform:rotate(360deg);
61
66
  }
62
67
  }
63
- ._allVariants_3sp1p2_48{
68
+ ._allVariants_1npbgia_48{
64
69
  aspect-ratio:var(--rs-icon-ar-width, 1) / var(--rs-icon-ar-height, 1);
65
70
  container:rs-icon / size;
66
71
  }
67
- ._variant16_3sp1p2_53,
68
- ._variant20_3sp1p2_54,
69
- ._variant24_3sp1p2_55{
72
+ ._variant16_1npbgia_53,
73
+ ._variant20_1npbgia_54,
74
+ ._variant24_1npbgia_55{
70
75
  display:none;
71
76
  }
72
- ._variant28_3sp1p2_58{
77
+ ._variant28_1npbgia_58{
73
78
  display:block;
74
79
  }
75
80
  @container rs-icon (max-height: 24px){
76
- ._variant24_3sp1p2_55{
81
+ ._variant24_1npbgia_55{
77
82
  display:block;
78
83
  }
79
- ._variant28_3sp1p2_58{
84
+ ._variant28_1npbgia_58{
80
85
  display:none;
81
86
  }
82
87
  }
83
88
  @container rs-icon (max-height: 20px){
84
- ._variant20_3sp1p2_54{
89
+ ._variant20_1npbgia_54{
85
90
  display:block;
86
91
  }
87
- ._variant24_3sp1p2_55{
92
+ ._variant24_1npbgia_55{
88
93
  display:none;
89
94
  }
90
95
  }
91
96
  @container rs-icon (max-height: 16px){
92
- ._variant16_3sp1p2_53{
97
+ ._variant16_1npbgia_53{
93
98
  display:block;
94
99
  }
95
- ._variant20_3sp1p2_54{
100
+ ._variant20_1npbgia_54{
96
101
  display:none;
97
102
  }
98
103
  }
99
- ._themeLight_1fi1hk_6{
104
+ @property --_rs-theme-dark-coefficient{
105
+ syntax:'<number>';
106
+ inherits:true;
107
+ initial-value:0;
108
+ }
109
+ ._themeLight_1n76usd_6{
100
110
  --rs-theme-dark:0;
101
111
  }
102
- ._themeDark_1fi1hk_9{
112
+ ._themeDark_1n76usd_9{
103
113
  --rs-theme-dark:1;
104
114
  }
105
- ._sizeS_1fi1hk_13{
115
+ ._sizeS_1n76usd_13{
106
116
  --_rs-collapse-vertical-padding:6px;
107
117
  --_rs-collapse-horizontal-padding:8px;
108
118
  --_rs-collapse-icon-size:20px;
109
119
  }
110
- ._sizeS_1fi1hk_13 > [data-rs-internal='collapse__button'] > [data-rs-internal='collapse__title']{
120
+ ._sizeS_1n76usd_13 > [data-rs-internal='collapse__button'] > [data-rs-internal='collapse__title']{
111
121
  --_rs-typography-letter-spacing:var(--rs-h5-letter-spacing, normal);
112
122
  --_rs-typography-text-transform:initial;
113
123
  --_rs-typography-font-variant-numeric:initial;
@@ -139,7 +149,7 @@
139
149
  --_rs-typography-link-external-standalone-border-offset-from-text-base:1.02em;
140
150
  --_rs-typography-link-border-bottom-width-from-text:2px;
141
151
  }
142
- ._sizeS_1fi1hk_13 > [data-rs-internal='collapse__content']{
152
+ ._sizeS_1n76usd_13 > [data-rs-internal='collapse__content']{
143
153
  --_rs-typography-letter-spacing:var(--rs-text-3-letter-spacing, 0.0045em);
144
154
  --_rs-typography-text-transform:initial;
145
155
  --_rs-typography-font-variant-numeric:initial;
@@ -174,12 +184,12 @@
174
184
  --_rs-typography-link-external-standalone-border-offset-from-text-base:1.02em;
175
185
  --_rs-typography-link-border-bottom-width-from-text:1px;
176
186
  }
177
- ._sizeM_1fi1hk_16{
187
+ ._sizeM_1n76usd_16{
178
188
  --_rs-collapse-vertical-padding:8px;
179
189
  --_rs-collapse-horizontal-padding:8px;
180
190
  --_rs-collapse-icon-size:24px;
181
191
  }
182
- ._sizeM_1fi1hk_16 > [data-rs-internal='collapse__button'] > [data-rs-internal='collapse__title']{
192
+ ._sizeM_1n76usd_16 > [data-rs-internal='collapse__button'] > [data-rs-internal='collapse__title']{
183
193
  --_rs-typography-letter-spacing:var(--rs-h4-letter-spacing, normal);
184
194
  --_rs-typography-text-transform:initial;
185
195
  --_rs-typography-font-variant-numeric:initial;
@@ -211,7 +221,7 @@
211
221
  --_rs-typography-link-external-standalone-border-offset-from-text-base:1.02em;
212
222
  --_rs-typography-link-border-bottom-width-from-text:2px;
213
223
  }
214
- ._sizeM_1fi1hk_16 > [data-rs-internal='collapse__content']{
224
+ ._sizeM_1n76usd_16 > [data-rs-internal='collapse__content']{
215
225
  --_rs-typography-letter-spacing:var(--rs-text-2-letter-spacing, 0.0015em);
216
226
  --_rs-typography-text-transform:initial;
217
227
  --_rs-typography-font-variant-numeric:initial;
@@ -250,16 +260,16 @@
250
260
  --_rs-typography-link-border-bottom-width-from-text:1px;
251
261
  }
252
262
  @media screen and (max-width: 640px){
253
- ._sizeM_1fi1hk_16 > [data-rs-internal='collapse__content']{
263
+ ._sizeM_1n76usd_16 > [data-rs-internal='collapse__content']{
254
264
  --_rs-typography-text-2-sm-list-li-margin-top-from-text:12px;
255
265
  }
256
266
  }
257
- ._sizeL_1fi1hk_19{
267
+ ._sizeL_1n76usd_19{
258
268
  --_rs-collapse-vertical-padding:12px;
259
269
  --_rs-collapse-horizontal-padding:16px;
260
270
  --_rs-collapse-icon-size:28px;
261
271
  }
262
- ._sizeL_1fi1hk_19 > [data-rs-internal='collapse__button'] > [data-rs-internal='collapse__title']{
272
+ ._sizeL_1n76usd_19 > [data-rs-internal='collapse__button'] > [data-rs-internal='collapse__title']{
263
273
  --_rs-typography-letter-spacing:var(--rs-h3-letter-spacing, normal);
264
274
  --_rs-typography-text-transform:initial;
265
275
  --_rs-typography-font-variant-numeric:initial;
@@ -291,7 +301,7 @@
291
301
  --_rs-typography-link-external-standalone-border-offset-from-text-base:1.02em;
292
302
  --_rs-typography-link-border-bottom-width-from-text:2px;
293
303
  }
294
- ._sizeL_1fi1hk_19 > [data-rs-internal='collapse__content']{
304
+ ._sizeL_1n76usd_19 > [data-rs-internal='collapse__content']{
295
305
  --_rs-typography-letter-spacing:var(--rs-text-1-letter-spacing, normal);
296
306
  --_rs-typography-text-transform:initial;
297
307
  --_rs-typography-font-variant-numeric:initial;
@@ -330,11 +340,11 @@
330
340
  --_rs-typography-link-border-bottom-width-from-text:1px;
331
341
  }
332
342
  @media screen and (max-width: 640px){
333
- ._sizeL_1fi1hk_19 > [data-rs-internal='collapse__content']{
343
+ ._sizeL_1n76usd_19 > [data-rs-internal='collapse__content']{
334
344
  --_rs-typography-text-1-sm-list-li-margin-top-from-text:16px;
335
345
  }
336
346
  }
337
- ._classic_1fi1hk_23{
347
+ ._classic_1n76usd_23{
338
348
  --_rs-collapse-active-theme-flip:0;
339
349
  --_rs-collapse-active-background:rgba(
340
350
  calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227),
@@ -348,7 +358,7 @@
348
358
  );
349
359
  --_rs-collapse-button-hover-color:rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227), 1);
350
360
  }
351
- ._rock_1fi1hk_26{
361
+ ._rock_1n76usd_26{
352
362
  --_rs-collapse-active-theme-flip:1;
353
363
  --_rs-collapse-active-background:rgb(calc(255 - var(--_rs-theme-dark-coefficient, 0)*230), calc(255 - var(--_rs-theme-dark-coefficient, 0)*230), calc(255 - var(--_rs-theme-dark-coefficient, 0)*227));
354
364
  --_rs-collapse-active-border-bottom-to-padding-multiplier:1;
@@ -359,7 +369,7 @@
359
369
  );
360
370
  --_rs-collapse-button-hover-color:rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227), 1);
361
371
  }
362
- ._clear_1fi1hk_29{
372
+ ._clear_1n76usd_29{
363
373
  --_rs-collapse-active-theme-flip:0;
364
374
  --_rs-collapse-active-background:transparent;
365
375
  --_rs-collapse-active-border-bottom-to-padding-multiplier:0;
@@ -370,27 +380,27 @@
370
380
  0.7
371
381
  );
372
382
  }
373
- ._hasBorderBottom_1fi1hk_33{
383
+ ._hasBorderBottom_1n76usd_33{
374
384
  --_rs-collapse-border-bottom-width-or-initial:1px;
375
385
  }
376
- ._leftIcon_1fi1hk_37{
386
+ ._leftIcon_1n76usd_37{
377
387
  --_rs-collapse-button-flex-direction:row;
378
388
  --_rs-collapse-icon-margin:0 var(--_rs-collapse-horizontal-padding) 0 0;
379
389
  --_rs-collapse-inner-wrapper-padding-left-base:calc(var(--_rs-collapse-horizontal-padding)*2 + var(--_rs-collapse-icon-size));
380
390
  }
381
- ._rightIcon_1fi1hk_40{
391
+ ._rightIcon_1n76usd_40{
382
392
  --_rs-collapse-button-flex-direction:row-reverse;
383
393
  --_rs-collapse-icon-margin:0 0 0 var(--_rs-collapse-horizontal-padding);
384
394
  --_rs-collapse-inner-wrapper-padding-left-base:var(
385
395
  --_rs-collapse-horizontal-padding
386
396
  );
387
397
  }
388
- ._disableLeftPadding_1fi1hk_44{
398
+ ._disableLeftPadding_1n76usd_44{
389
399
  --_rs-collapse-inner-wrapper-padding-left-from-disable-left-padding-or-initial:var(
390
400
  --_rs-collapse-horizontal-padding
391
401
  );
392
402
  }
393
- ._main_1fi1hk_48{
403
+ ._main_1n76usd_48{
394
404
  --_rs-theme-dark:var(
395
405
  --_rs-internal-force-theme-dark-consult-rescui-before-using,
396
406
  var(--rs-theme-dark, 0)
@@ -400,7 +410,7 @@
400
410
  --_rs-theme-light-coefficient:calc(1 - var(--_rs-theme-dark-coefficient));
401
411
  }
402
412
  @supports (color: color-mix(in srgb, #fff 50%, #000 50%)){
403
- ._main_1fi1hk_48{
413
+ ._main_1n76usd_48{
404
414
  --_rs-color-primary:color-mix(in srgb, var(--rs-color-primary-light-theme, #6B57FF) calc(100%*var(--_rs-theme-light-coefficient, 1)), var(--rs-color-primary-dark-theme, #8473FF) calc(100%*var(--_rs-theme-dark-coefficient, 0)));
405
415
  --_rs-color-primary-dim:color-mix(in srgb, var(--rs-color-primary-dim-light-theme, #8979ff) calc(100%*var(--_rs-theme-light-coefficient, 1)), var(--rs-color-primary-dim-dark-theme, #6f61d2) calc(100%*var(--_rs-theme-dark-coefficient, 0)));
406
416
  --_rs-color-primary-fog:color-mix(in srgb, var(--rs-color-primary-fog-light-theme, #e1ddff) calc(100%*var(--_rs-theme-light-coefficient, 1)), var(--rs-color-primary-fog-dark-theme, #2e2b49) calc(100%*var(--_rs-theme-dark-coefficient, 0)));
@@ -409,7 +419,7 @@
409
419
  }
410
420
  }
411
421
  @supports not (color: color-mix(in srgb, #fff 50%, #000 50%)){
412
- ._main_1fi1hk_48{
422
+ ._main_1n76usd_48{
413
423
  --_rs-color-primary:rgb(calc(var(--_rs-theme-light-coefficient, 1)*107 + var(--_rs-theme-dark-coefficient, 0)*132), calc(var(--_rs-theme-light-coefficient, 1)*87 + var(--_rs-theme-dark-coefficient, 0)*115), 255);
414
424
  --_rs-color-primary-dim:rgb(calc(var(--_rs-theme-light-coefficient, 1)*137 + var(--_rs-theme-dark-coefficient, 0)*111), calc(var(--_rs-theme-light-coefficient, 1)*121 + var(--_rs-theme-dark-coefficient, 0)*97), calc(var(--_rs-theme-light-coefficient, 1)*255 + var(--_rs-theme-dark-coefficient, 0)*210));
415
425
  --_rs-color-primary-fog:rgb(calc(var(--_rs-theme-light-coefficient, 1)*225 + var(--_rs-theme-dark-coefficient, 0)*46), calc(var(--_rs-theme-light-coefficient, 1)*221 + var(--_rs-theme-dark-coefficient, 0)*43), calc(var(--_rs-theme-light-coefficient, 1)*255 + var(--_rs-theme-dark-coefficient, 0)*73));
@@ -417,7 +427,7 @@
417
427
  --_rs-color-primary-t-fog:rgba(calc(var(--_rs-theme-light-coefficient, 1)*107 + var(--_rs-theme-dark-coefficient, 0)*132), calc(var(--_rs-theme-light-coefficient, 1)*87 + var(--_rs-theme-dark-coefficient, 0)*115), 255, calc(var(--_rs-theme-light-coefficient, 1)*0.2 + var(--_rs-theme-dark-coefficient, 0)*0.3));
418
428
  }
419
429
  }
420
- ._main_1fi1hk_48 {
430
+ ._main_1n76usd_48 {
421
431
  --_rs-collapse-border-bottom-width:var(
422
432
  --_rs-collapse-border-bottom-width-or-initial,
423
433
  0px
@@ -432,9 +442,9 @@
432
442
  border-bottom:var(--_rs-collapse-border-bottom-width) solid rgba(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227), 0.2);
433
443
  border-radius:var(--rs-collapse-border-radius, 0px);
434
444
  }
435
- ._main_1fi1hk_48._opening_1fi1hk_59,
436
- ._main_1fi1hk_48._opened_1fi1hk_60,
437
- ._main_1fi1hk_48._closing_1fi1hk_61{
445
+ ._main_1n76usd_48._opening_1n76usd_59,
446
+ ._main_1n76usd_48._opened_1n76usd_60,
447
+ ._main_1n76usd_48._closing_1n76usd_61{
438
448
  --rs-theme-flip:var(--_rs-collapse-active-theme-flip);
439
449
 
440
450
  padding-bottom:calc(var(--_rs-collapse-border-bottom-width)*var(--_rs-collapse-active-border-bottom-to-padding-multiplier));
@@ -444,7 +454,7 @@
444
454
  background:var(--_rs-collapse-active-background);
445
455
  }
446
456
  @media (hover: hover){
447
- ._main_1fi1hk_48:hover{
457
+ ._main_1n76usd_48:hover{
448
458
  --rs-theme-flip:var(--_rs-collapse-active-theme-flip);
449
459
 
450
460
  padding-bottom:calc(var(--_rs-collapse-border-bottom-width)*var(--_rs-collapse-active-border-bottom-to-padding-multiplier));
@@ -454,7 +464,7 @@
454
464
  background:var(--_rs-collapse-active-background);
455
465
  }
456
466
  }
457
- ._title_1fi1hk_95{
467
+ ._title_1n76usd_95{
458
468
  letter-spacing:var(
459
469
  --rs-text-base-letter-spacing,
460
470
  var(--_rs-typography-letter-spacing)
@@ -471,7 +481,7 @@
471
481
 
472
482
  color:inherit;
473
483
  }
474
- ._content_1fi1hk_103{
484
+ ._content_1n76usd_103{
475
485
  letter-spacing:var(
476
486
  --rs-text-base-letter-spacing,
477
487
  var(--_rs-typography-letter-spacing)
@@ -488,26 +498,32 @@
488
498
  rgb(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227))
489
499
  );
490
500
 
491
- will-change:height;
501
+ display:grid;
502
+
503
+ overflow:hidden;
492
504
 
493
- height:0;
505
+ grid-template-rows:minmax(0, 0fr);
506
+
507
+ will-change:grid-template-rows;
494
508
  }
495
- ._closed_1fi1hk_111 > ._content_1fi1hk_103{
496
- display:none;
509
+ ._animationEnabled_1n76usd_115 ._content_1n76usd_103{
510
+ transition:grid-template-rows 300ms var(--rs-transition-function, ease);
497
511
  }
498
- ._opened_1fi1hk_60 > ._content_1fi1hk_103{
499
- height:initial;
512
+ ._opening_1n76usd_59 > ._content_1n76usd_103,
513
+ ._opened_1n76usd_60 > ._content_1n76usd_103{
514
+ grid-template-rows:minmax(0, 1fr);
500
515
  }
501
- ._opening_1fi1hk_59 > ._content_1fi1hk_103,
502
- ._closingTransition_1fi1hk_120 > ._content_1fi1hk_103{
503
- overflow:hidden;
504
-
505
- transition:height 300ms var(--rs-transition-function, ease);
516
+ ._opened_1n76usd_60 > ._content_1n76usd_103{
517
+ overflow:visible;
518
+ }
519
+ ._closed_1n76usd_128 > ._content_1n76usd_103{
520
+ visibility:hidden;
506
521
  }
507
- ._innerWrapper_1fi1hk_127{
522
+ ._innerWrapper_1n76usd_133{
523
+ min-height:0;
508
524
  padding:0 var(--_rs-collapse-horizontal-padding) var(--_rs-collapse-horizontal-padding) var(--_rs-collapse-inner-wrapper-padding-left);
509
525
  }
510
- ._button_1fi1hk_133{
526
+ ._button_1n76usd_140{
511
527
  color:var(
512
528
  --rs-color-hard,
513
529
  rgb(calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(25 + var(--_rs-theme-dark-coefficient, 0)*230), calc(28 + var(--_rs-theme-dark-coefficient, 0)*227))
@@ -535,29 +551,31 @@
535
551
 
536
552
  font:inherit;
537
553
  line-height:normal;
538
- transition:var(--_rs-collapse-button-transition);
539
554
  -webkit-font-smoothing:inherit;
540
555
  -moz-osx-font-smoothing:inherit;
541
556
  -webkit-appearance:none;
542
557
  }
543
- ._button_1fi1hk_133::-moz-focus-inner{
558
+ ._button_1n76usd_140::-moz-focus-inner{
544
559
  padding:0;
545
560
 
546
561
  border:0;
547
562
  }
548
- ._button_1fi1hk_133:focus{
563
+ ._animationEnabled_1n76usd_115 ._button_1n76usd_140{
564
+ transition:var(--_rs-collapse-button-transition);
565
+ }
566
+ ._button_1n76usd_140:focus{
549
567
  outline:none;
550
568
  }
551
- ._button_1fi1hk_133:focus[data-focus-method='key']{
569
+ ._button_1n76usd_140:focus[data-focus-method='key']{
552
570
  box-shadow:var(--_rs-color-primary-t-dim) 0 0 0 4px;
553
571
  }
554
572
  @media (hover: hover){
555
- ._button_1fi1hk_133:hover{
573
+ ._button_1n76usd_140:hover{
556
574
  color:var(--_rs-collapse-button-hover-color);
557
575
  background:var(--_rs-collapse-button-hover-background);
558
576
  }
559
577
  }
560
- ._icon_1fi1hk_186{
578
+ ._icon_1n76usd_196{
561
579
  position:relative;
562
580
  top:0;
563
581
  left:0;
@@ -568,39 +586,43 @@
568
586
  height:var(--_rs-collapse-icon-size);
569
587
  margin:var(--_rs-collapse-icon-margin);
570
588
 
571
- transition:transform 300ms var(--rs-transition-function, ease);
589
+ transform:rotate(0);
590
+
572
591
  transform-origin:center center;
573
592
 
574
593
  will-change:transform;
575
594
  }
576
- ._opening_1fi1hk_59._iconPlus_1fi1hk_202 > ._button_1fi1hk_133 > ._icon_1fi1hk_186,
577
- ._opened_1fi1hk_60._iconPlus_1fi1hk_202 > ._button_1fi1hk_133 > ._icon_1fi1hk_186{
595
+ ._animationEnabled_1n76usd_115 ._icon_1n76usd_196{
596
+ transition:transform 300ms var(--rs-transition-function, ease);
597
+ }
598
+ ._opening_1n76usd_59._iconPlus_1n76usd_217 > ._button_1n76usd_140 > ._icon_1n76usd_196,
599
+ ._opened_1n76usd_60._iconPlus_1n76usd_217 > ._button_1n76usd_140 > ._icon_1n76usd_196{
578
600
  transform:rotate(45deg);
579
601
  }
580
- ._opening_1fi1hk_59._iconArrow_1fi1hk_207 > ._button_1fi1hk_133 > ._icon_1fi1hk_186,
581
- ._opened_1fi1hk_60._iconArrow_1fi1hk_207 > ._button_1fi1hk_133 > ._icon_1fi1hk_186{
602
+ ._opening_1n76usd_59._iconArrow_1n76usd_222 > ._button_1n76usd_140 > ._icon_1n76usd_196,
603
+ ._opened_1n76usd_60._iconArrow_1n76usd_222 > ._button_1n76usd_140 > ._icon_1n76usd_196{
582
604
  transform:rotate(90deg);
583
605
  }
584
- ._accordion_1fi1hk_213{
606
+ ._accordion_1n76usd_228{
585
607
  display:flex;
586
608
  flex-direction:column;
587
609
  row-gap:var(--_rs-collapse-accordion-gap);
588
610
  }
589
- ._accordionGap0_1fi1hk_218{
611
+ ._accordionGap0_1n76usd_233{
590
612
  --_rs-collapse-accordion-gap:0px;
591
613
  }
592
- ._accordionGap8_1fi1hk_221{
614
+ ._accordionGap8_1n76usd_236{
593
615
  --_rs-collapse-accordion-gap:8px;
594
616
  }
595
- ._accordionGap12_1fi1hk_224{
617
+ ._accordionGap12_1n76usd_239{
596
618
  --_rs-collapse-accordion-gap:12px;
597
619
  }
598
- ._accordionGap16_1fi1hk_227{
620
+ ._accordionGap16_1n76usd_242{
599
621
  --_rs-collapse-accordion-gap:16px;
600
622
  }
601
- ._accordionGap24_1fi1hk_230{
623
+ ._accordionGap24_1n76usd_245{
602
624
  --_rs-collapse-accordion-gap:24px;
603
625
  }
604
- ._accordionGap32_1fi1hk_233{
626
+ ._accordionGap32_1n76usd_248{
605
627
  --_rs-collapse-accordion-gap:32px;
606
628
  }
@@ -1,3 +1,8 @@
1
+ @property --_rs-theme-dark-coefficient{
2
+ syntax:'<number>';
3
+ inherits:true;
4
+ initial-value:0;
5
+ }
1
6
  @define-mixin rs-collapse-size-s{
2
7
  &[class]{
3
8
  --_rs-collapse-vertical-padding:6px;
@@ -1,3 +1,8 @@
1
+ @property --_rs-theme-dark-coefficient{
2
+ syntax:'<number>';
3
+ inherits:true;
4
+ initial-value:0;
5
+ }
1
6
  @define-mixin rs-collapse-size-s{
2
7
  &[class]{
3
8
  --_rs-collapse-vertical-padding:6px;
@@ -1,17 +1,13 @@
1
+ import type { RefObject } from 'react';
1
2
  export declare enum COLLAPSE_STATES {
2
3
  OPENING = "OPENING",
3
4
  OPEN = "OPEN",
4
5
  CLOSING = "CLOSING",
5
6
  CLOSE = "CLOSE"
6
7
  }
7
- export declare function useCollapseState({ shouldBeOpened, cancelAnimation }: {
8
+ type UseCollapseStateOptions = {
8
9
  shouldBeOpened: boolean;
9
- cancelAnimation?: boolean;
10
- }): {
11
- onAnimationEnd: () => void;
12
- state: COLLAPSE_STATES;
13
- };
14
- export declare function useStartedClosing(state: COLLAPSE_STATES): {
15
- isStartedClosing: boolean;
16
- contentRef: import("react").RefObject<HTMLDivElement>;
10
+ contentRef: RefObject<HTMLDivElement | null>;
17
11
  };
12
+ export declare function useCollapseState({ shouldBeOpened, contentRef }: UseCollapseStateOptions): COLLAPSE_STATES;
13
+ export {};
@@ -1,5 +1,9 @@
1
1
  "use client";
2
- import { useState, useRef, useCallback } from 'react';
2
+ import { useState, useCallback, useEffect, useLayoutEffect } from 'react';
3
+ const useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;
4
+
5
+ const getCollapseTransition = element => element.getAnimations().find(animation => animation.transitionProperty === 'grid-template-rows');
6
+
3
7
  var COLLAPSE_STATES;
4
8
 
5
9
  (function (COLLAPSE_STATES) {
@@ -7,69 +11,107 @@ var COLLAPSE_STATES;
7
11
  COLLAPSE_STATES["OPEN"] = "OPEN";
8
12
  COLLAPSE_STATES["CLOSING"] = "CLOSING";
9
13
  COLLAPSE_STATES["CLOSE"] = "CLOSE";
10
- })(COLLAPSE_STATES || (COLLAPSE_STATES = {})); // eslint-disable-next-line complexity
14
+ })(COLLAPSE_STATES || (COLLAPSE_STATES = {}));
15
+
16
+ function getStateForTarget(state, shouldBeOpened) {
17
+ if (shouldBeOpened) {
18
+ return state === COLLAPSE_STATES.OPEN || state === COLLAPSE_STATES.OPENING ? state : COLLAPSE_STATES.OPENING;
19
+ }
11
20
 
21
+ if (state === COLLAPSE_STATES.CLOSE || state === COLLAPSE_STATES.CLOSING) {
22
+ return state;
23
+ }
24
+
25
+ return COLLAPSE_STATES.CLOSING;
26
+ }
12
27
 
13
28
  function useCollapseState(_ref) {
14
29
  let {
15
30
  shouldBeOpened,
16
- cancelAnimation
31
+ contentRef
17
32
  } = _ref;
18
- const [, setDummyState] = useState(false);
19
- const stateRef = useRef(COLLAPSE_STATES.CLOSE);
20
- const onAnimationEnd = useCallback(() => {
21
- if ((stateRef.current === COLLAPSE_STATES.CLOSING || stateRef.current === COLLAPSE_STATES.OPENING) && !shouldBeOpened) {
22
- stateRef.current = COLLAPSE_STATES.CLOSE; //force rerender
33
+ const [state, setState] = useState(shouldBeOpened ? COLLAPSE_STATES.OPEN : COLLAPSE_STATES.CLOSE);
34
+ const completeTransition = useCallback(expectedState => {
35
+ setState(currentState => {
36
+ if (currentState !== expectedState) {
37
+ return currentState;
38
+ }
39
+
40
+ if (expectedState === COLLAPSE_STATES.OPENING) {
41
+ return COLLAPSE_STATES.OPEN;
42
+ }
23
43
 
24
- setDummyState(s => !s);
25
- } else if (stateRef.current === COLLAPSE_STATES.OPENING && shouldBeOpened) {
26
- stateRef.current = COLLAPSE_STATES.OPEN; //force rerender
44
+ if (expectedState === COLLAPSE_STATES.CLOSING) {
45
+ return COLLAPSE_STATES.CLOSE;
46
+ }
27
47
 
28
- setDummyState(s => !s);
48
+ return currentState;
49
+ });
50
+ }, []); // Track the grid track transition that currently belongs to OPENING/CLOSING:
51
+ // - normally, complete the phase after the track reaches its target;
52
+ // - a direction change can replace the transition, so follow the latest one;
53
+ // - if the phase changes, cleanup invalidates its waiter, so an old
54
+ // transition cannot complete a newer phase;
55
+ // - if no transition is created (for example, its duration is 0s), complete
56
+ // the phase immediately.
57
+
58
+ useIsomorphicLayoutEffect(() => {
59
+ if (state !== COLLAPSE_STATES.OPENING && state !== COLLAPSE_STATES.CLOSING) {
60
+ return undefined;
29
61
  }
30
- }, [shouldBeOpened]);
31
62
 
32
- if (shouldBeOpened && stateRef.current !== COLLAPSE_STATES.OPEN) {
33
- stateRef.current = cancelAnimation ? COLLAPSE_STATES.OPEN : COLLAPSE_STATES.OPENING;
34
- } else if ((stateRef.current === COLLAPSE_STATES.OPEN || stateRef.current === COLLAPSE_STATES.OPENING) && !shouldBeOpened) {
35
- stateRef.current = cancelAnimation ? COLLAPSE_STATES.CLOSE : COLLAPSE_STATES.CLOSING;
36
- }
63
+ const contentElement = contentRef.current;
37
64
 
38
- return {
39
- onAnimationEnd,
40
- state: stateRef.current
41
- };
42
- }
65
+ if (!contentElement) {
66
+ return undefined;
67
+ }
43
68
 
44
- function useStartedClosing(state) {
45
- const isStartedClosingRef = useRef(false);
46
- const prevState = useRef(state);
47
- const contentRef = useRef(null);
48
- const [, setDummyState] = useState(false);
69
+ let isCurrentPhase = true;
49
70
 
50
- if (prevState.current === COLLAPSE_STATES.OPEN && state === COLLAPSE_STATES.CLOSING) {
51
- isStartedClosingRef.current = true; // the next frame we need to force layout recalculations and new render
71
+ const completeCurrentPhase = () => {
72
+ if (isCurrentPhase) {
73
+ completeTransition(state);
74
+ }
75
+ };
52
76
 
53
- if (typeof window !== 'undefined') {
54
- requestAnimationFrame(() => {
55
- if (!contentRef.current || !isStartedClosingRef.current) {
56
- return;
57
- } // force layout recalc, without this step firefox doesn't register style values for transitions
58
- // eslint-disable-next-line no-unused-expressions
77
+ const waitForCurrentTransition = previousTransition => {
78
+ if (!isCurrentPhase) {
79
+ return Promise.resolve();
80
+ }
59
81
 
82
+ const transition = getCollapseTransition(contentElement);
60
83
 
61
- contentRef.current.offsetHeight;
62
- isStartedClosingRef.current = false;
63
- setDummyState(s => !s);
64
- });
65
- }
84
+ if (!transition || transition === previousTransition) {
85
+ return Promise.resolve();
86
+ }
87
+
88
+ return transition.finished.then(() => {
89
+ if (!isCurrentPhase) {
90
+ return Promise.resolve();
91
+ }
92
+
93
+ const replacementTransition = getCollapseTransition(contentElement);
94
+
95
+ if (replacementTransition && replacementTransition !== transition) {
96
+ return waitForCurrentTransition(transition);
97
+ }
98
+
99
+ return Promise.resolve();
100
+ }, () => waitForCurrentTransition(transition));
101
+ };
102
+
103
+ waitForCurrentTransition().then(completeCurrentPhase);
104
+ return () => {
105
+ isCurrentPhase = false;
106
+ };
107
+ }, [completeTransition, contentRef, state]);
108
+ const stateForTarget = getStateForTarget(state, shouldBeOpened); // React retries this component before rendering its children when the phase changes.
109
+
110
+ if (stateForTarget !== state) {
111
+ setState(stateForTarget);
66
112
  }
67
113
 
68
- prevState.current = state;
69
- return {
70
- isStartedClosing: isStartedClosingRef.current,
71
- contentRef
72
- };
114
+ return state;
73
115
  }
74
116
 
75
- export { COLLAPSE_STATES, useCollapseState, useStartedClosing };
117
+ export { COLLAPSE_STATES, useCollapseState };
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ declare function useFallbackId(): number;
3
+ export declare const useSafeId: typeof React.useId | typeof useFallbackId;
4
+ export {};
@@ -0,0 +1,10 @@
1
+ import React, { useState } from 'react';
2
+ let nextFallbackId = 0;
3
+
4
+ function useFallbackId() {
5
+ const [id] = useState(() => nextFallbackId++);
6
+ return id;
7
+ }
8
+
9
+ const useSafeId = React.useId ?? useFallbackId;
10
+ export { useSafeId };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rescui/collapse",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "",
5
5
  "license": "Apache-2.0",
6
6
  "author": "JetBrains",
@@ -17,7 +17,6 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@babel/runtime-corejs3": "^7.26.0",
20
- "@rescui/use-resize-observer": "^0.3.3",
21
20
  "classnames": "^2.2.6"
22
21
  },
23
22
  "peerDependencies": {
@@ -26,9 +25,9 @@
26
25
  "react": ">=16.8.0 <20"
27
26
  },
28
27
  "devDependencies": {
29
- "@rescui/colors": "^0.3.2",
28
+ "@rescui/colors": "^0.3.3",
30
29
  "@rescui/scripts": "^0.5.2",
31
- "@rescui/typography": "^0.27.3",
30
+ "@rescui/typography": "^0.27.4",
32
31
  "@rescui/visual-regression": "^0.1.4",
33
32
  "@types/classnames": "^2.2.11"
34
33
  },
@@ -37,5 +36,5 @@
37
36
  "build-pcss-api": "rescui-scripts build-pcss-api --file public-api.p.css"
38
37
  },
39
38
  "nx": {},
40
- "gitHead": "7614b4519a4716fbf1151d94c97fda48eab60800"
39
+ "gitHead": "3711cbfc0c797014395421b008aa5331d6d47c6e"
41
40
  }