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