@designbasekorea/figma-ui 0.6.0 → 0.6.3

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.
package/dist/index.js CHANGED
@@ -106,7 +106,9 @@ const FigmaSection = ({ title, dataCategory, iconButton, children, marginBottom,
106
106
  const clipRef = React.useRef(null);
107
107
  const innerRef = React.useRef(null);
108
108
  const animatingRef = React.useRef(false);
109
+ const isInitialMountRef = React.useRef(true);
109
110
  const [collapsed, setCollapsed] = React.useState(defaultCollapsed);
111
+ const [contentHidden, setContentHidden] = React.useState(defaultCollapsed);
110
112
  const sectionStyle = marginBottom ? { marginBottom: `${marginBottom}px` } : undefined;
111
113
  const classes = [
112
114
  'designbase-figma-section',
@@ -119,38 +121,42 @@ const FigmaSection = ({ title, dataCategory, iconButton, children, marginBottom,
119
121
  const toggle = () => {
120
122
  if (!collapsible)
121
123
  return;
122
- setCollapsed(v => {
123
- const next = !v;
124
+ setCollapsed((prev) => {
125
+ const next = !prev;
124
126
  onCollapseChange?.(next, dataCategory);
125
- animate(next);
126
127
  return next;
127
128
  });
128
129
  };
129
- const animate = (toCollapsed) => {
130
+ const animate = (toCollapsed, onComplete) => {
130
131
  const clip = clipRef.current;
131
132
  const inner = innerRef.current;
132
133
  if (!clip || !inner)
133
134
  return;
134
135
  const transitionMs = 250;
135
- const setH = (h) => { clip.style.height = h; };
136
+ const setH = (h) => {
137
+ clip.style.height = h;
138
+ };
136
139
  if (animatingRef.current) {
137
140
  const current = `${clip.getBoundingClientRect().height}px`;
138
141
  clip.style.transition = 'none';
139
142
  setH(current);
140
- clip.offsetHeight;
143
+ void clip.offsetHeight;
141
144
  clip.style.transition = '';
142
145
  }
143
146
  animatingRef.current = true;
144
147
  if (toCollapsed) {
148
+ inner.classList.remove('is-collapsed');
145
149
  const start = `${inner.scrollHeight}px`;
146
150
  setH(start);
147
- clip.offsetHeight;
151
+ void clip.offsetHeight;
148
152
  setH('0px');
149
153
  }
150
154
  else {
155
+ inner.classList.remove('is-collapsed');
156
+ const targetHeight = inner.scrollHeight;
151
157
  setH('0px');
152
- clip.offsetHeight;
153
- setH(`${inner.scrollHeight}px`);
158
+ void clip.offsetHeight;
159
+ setH(`${targetHeight}px`);
154
160
  }
155
161
  const onEnd = (e) => {
156
162
  if (e.propertyName !== 'height')
@@ -160,6 +166,7 @@ const FigmaSection = ({ title, dataCategory, iconButton, children, marginBottom,
160
166
  setH('auto');
161
167
  }
162
168
  animatingRef.current = false;
169
+ onComplete?.();
163
170
  };
164
171
  clip.addEventListener('transitionend', onEnd);
165
172
  window.setTimeout(() => {
@@ -168,15 +175,29 @@ const FigmaSection = ({ title, dataCategory, iconButton, children, marginBottom,
168
175
  if (!toCollapsed)
169
176
  setH('auto');
170
177
  animatingRef.current = false;
178
+ onComplete?.();
171
179
  }, transitionMs + 50);
172
180
  };
173
- React.useEffect(() => {
174
- const clip = clipRef.current;
175
- const inner = innerRef.current;
176
- if (!clip || !inner)
181
+ React.useLayoutEffect(() => {
182
+ if (!collapsible)
177
183
  return;
178
- clip.style.height = collapsed ? '0px' : 'auto';
179
- }, []);
184
+ if (isInitialMountRef.current) {
185
+ isInitialMountRef.current = false;
186
+ const clip = clipRef.current;
187
+ if (clip) {
188
+ clip.style.height = collapsed ? '0px' : 'auto';
189
+ }
190
+ setContentHidden(collapsed);
191
+ return;
192
+ }
193
+ if (collapsed) {
194
+ animate(true, () => setContentHidden(true));
195
+ }
196
+ else {
197
+ setContentHidden(false);
198
+ animate(false);
199
+ }
200
+ }, [collapsed, collapsible]);
180
201
  React.useEffect(() => {
181
202
  if (collapsed)
182
203
  return;
@@ -203,14 +224,14 @@ const FigmaSection = ({ title, dataCategory, iconButton, children, marginBottom,
203
224
  ? resolveText(t, title)
204
225
  : title,
205
226
  badge && (React.createElement(ui.Badge, { variant: "secondary", size: "s" }, badge)))),
206
- React.createElement("div", { className: "designbase-figma-section__controls" },
227
+ React.createElement("div", { className: "designbase-figma-section__controls", onClick: (e) => e.stopPropagation() },
207
228
  iconButton,
208
229
  collapsible && (React.createElement("span", { className: `designbase-figma-section__collapse-icon ${collapsed ? 'designbase-figma-section__collapse-icon--collapsed' : ''}` },
209
230
  React.createElement(icons.ChevronDownIcon, { size: 16 }))),
210
231
  onToggle && (React.createElement(ui.Toggle, { checked: isEnabled, onChange: () => onToggle(dataCategory), size: "s" }))))),
211
232
  React.createElement("div", { className: `designbase-figma-section__content ${!isEnabled ? 'designbase-figma-section__content--hidden' : ''}` },
212
233
  React.createElement("div", { ref: clipRef, className: "designbase-figma-section__content-clip" },
213
- React.createElement("div", { ref: innerRef, className: `designbase-figma-section__content-inner ${collapsible && collapsed ? 'is-collapsed' : ''}` }, children)))));
234
+ React.createElement("div", { ref: innerRef, className: `designbase-figma-section__content-inner ${collapsible && contentHidden ? 'is-collapsed' : ''}` }, children)))));
214
235
  };
215
236
  FigmaSection.displayName = 'FigmaSection';
216
237
  const scrollToSection = (category, headerHeight = 94) => {