@moises.ai/design-system 3.5.6 → 3.6.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.
@@ -0,0 +1,368 @@
1
+ import { useEffect, useState } from 'react'
2
+ import { Badge, Button, Card, Flex, IconButton, Text } from '../../index'
3
+ import { DotsVerticalIcon } from '../../icons'
4
+ import { Extension, useNavigation, useScreen } from './Extension'
5
+
6
+ const mockMoises = {
7
+ extension: { close: () => console.log('extension.close()') },
8
+ }
9
+
10
+ const sidebarDecorator = (Story) => (
11
+ <div
12
+ style={{
13
+ width: 300,
14
+ height: 500,
15
+ border: '1px solid var(--gray-a6)',
16
+ borderRadius: 8,
17
+ overflow: 'hidden',
18
+ display: 'flex',
19
+ flexDirection: 'column',
20
+ }}
21
+ >
22
+ <Story />
23
+ </div>
24
+ )
25
+
26
+ export default {
27
+ title: 'Extensions/Extension',
28
+ decorators: [sidebarDecorator],
29
+ parameters: { layout: 'centered' },
30
+ }
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // Simple mode (flat layout, no navigation)
34
+ // ---------------------------------------------------------------------------
35
+
36
+ export const Simple = {
37
+ name: 'Simple (Header + Content + Footer)',
38
+ render: () => (
39
+ <Extension moises={mockMoises}>
40
+ <Extension.Header title="My Extension">
41
+ <Button variant="ghost" size="1">Action</Button>
42
+ </Extension.Header>
43
+ <Extension.Content>
44
+ <Card>Card content 1</Card>
45
+ <Card>Card content 2</Card>
46
+ <Card>Card content 3</Card>
47
+ </Extension.Content>
48
+ <Extension.Footer>
49
+ <Button variant="ghost" size="1">Footer Action</Button>
50
+ </Extension.Footer>
51
+ </Extension>
52
+ ),
53
+ }
54
+
55
+ export const HeaderOnly = {
56
+ name: 'Header Only',
57
+ render: () => (
58
+ <Extension moises={mockMoises}>
59
+ <Extension.Header title="Minimal" />
60
+ <Extension.Content>
61
+ <Text size="2">Content with a simple header above.</Text>
62
+ </Extension.Content>
63
+ </Extension>
64
+ ),
65
+ }
66
+
67
+ export const HeaderWithBackButton = {
68
+ name: 'Header with Back Button',
69
+ render: () => (
70
+ <Extension moises={mockMoises}>
71
+ <Extension.Header title="Detail View" onBack={() => console.log('onBack')} />
72
+ <Extension.Content>
73
+ <Text size="2">Passing `onBack` renders a back arrow on the left.</Text>
74
+ </Extension.Content>
75
+ </Extension>
76
+ ),
77
+ }
78
+
79
+ export const HeaderCustomLeft = {
80
+ name: 'Header with Custom Left',
81
+ render: () => (
82
+ <Extension moises={mockMoises}>
83
+ <Extension.Header
84
+ title="Custom Left"
85
+ headerLeft={<Badge variant="soft" size="1">v2</Badge>}
86
+ />
87
+ <Extension.Content>
88
+ <Text size="2">`headerLeft` replaces the default back button.</Text>
89
+ </Extension.Content>
90
+ </Extension>
91
+ ),
92
+ }
93
+
94
+ export const HeaderCustomRight = {
95
+ name: 'Header with Custom Right',
96
+ render: () => (
97
+ <Extension moises={mockMoises}>
98
+ <Extension.Header
99
+ title="Options"
100
+ headerRight={
101
+ <IconButton variant="ghost" color="gray" size="1">
102
+ <DotsVerticalIcon width={16} />
103
+ </IconButton>
104
+ }
105
+ />
106
+ <Extension.Content>
107
+ <Text size="2">`headerRight` adds actions before the close button.</Text>
108
+ </Extension.Content>
109
+ </Extension>
110
+ ),
111
+ }
112
+
113
+ export const HeaderNoClose = {
114
+ name: 'Header without Close Button',
115
+ render: () => (
116
+ <Extension moises={mockMoises}>
117
+ <Extension.Header title="No Close" allowClose={false} />
118
+ <Extension.Content>
119
+ <Text size="2">Close button hidden via `allowClose={'{false}'}`.</Text>
120
+ </Extension.Content>
121
+ </Extension>
122
+ ),
123
+ }
124
+
125
+ export const ScrollableContent = {
126
+ name: 'Scrollable Content',
127
+ render: () => (
128
+ <Extension moises={mockMoises}>
129
+ <Extension.Header title="Scrollable" />
130
+ <Extension.Content>
131
+ {Array.from({ length: 20 }, (_, i) => (
132
+ <Card key={i}>Item {i + 1}</Card>
133
+ ))}
134
+ </Extension.Content>
135
+ <Extension.Footer>
136
+ <Text size="1" color="gray">Footer stays pinned</Text>
137
+ </Extension.Footer>
138
+ </Extension>
139
+ ),
140
+ }
141
+
142
+ // ---------------------------------------------------------------------------
143
+ // Navigator mode (screen stack with push/pop)
144
+ // ---------------------------------------------------------------------------
145
+
146
+ const ITEMS = [
147
+ { id: 'drums', name: 'Drums', desc: 'Acoustic drum kit with multiple mic positions' },
148
+ { id: 'bass', name: 'Bass', desc: 'Electric bass recorded through DI and amp' },
149
+ { id: 'guitar', name: 'Guitar', desc: 'Clean electric guitar with stereo chorus' },
150
+ { id: 'vocals', name: 'Vocals', desc: 'Lead vocals with studio compression' },
151
+ { id: 'keys', name: 'Keys', desc: 'Rhodes piano through a rotary speaker sim' },
152
+ ]
153
+
154
+ function HomeScreen() {
155
+ const { push } = useNavigation()
156
+
157
+ return (
158
+ <>
159
+ <Extension.Content>
160
+ {ITEMS.map((item) => (
161
+ <Card
162
+ key={item.id}
163
+ style={{ cursor: 'pointer' }}
164
+ onClick={() => push('detail', { itemId: item.id, itemName: item.name })}
165
+ >
166
+ <Flex direction="column" gap="1">
167
+ <Text size="2" weight="medium">{item.name}</Text>
168
+ <Text size="1" color="gray">{item.desc}</Text>
169
+ </Flex>
170
+ </Card>
171
+ ))}
172
+ </Extension.Content>
173
+ <Extension.Footer>
174
+ <Button variant="ghost" size="1" onClick={() => push('settings')}>
175
+ View Stack
176
+ </Button>
177
+ </Extension.Footer>
178
+ </>
179
+ )
180
+ }
181
+
182
+ function DetailScreen() {
183
+ const { push } = useNavigation()
184
+ const { params, setOptions } = useScreen()
185
+ const item = ITEMS.find((i) => i.id === params.itemId)
186
+
187
+ useEffect(() => {
188
+ setOptions({ title: params.itemName })
189
+ }, [params.itemName])
190
+
191
+ if (!item) {
192
+ return (
193
+ <Extension.Content>
194
+ <Text size="2" color="gray">Item not found.</Text>
195
+ </Extension.Content>
196
+ )
197
+ }
198
+
199
+ return (
200
+ <Extension.Content>
201
+ <Flex direction="column" gap="2">
202
+ <Text size="2" weight="medium">{item.name}</Text>
203
+ <Text size="2" color="gray">{item.desc}</Text>
204
+ </Flex>
205
+ <Button variant="soft" size="2" onClick={() => push('editor', { itemId: item.id })}>
206
+ Open Editor
207
+ </Button>
208
+ </Extension.Content>
209
+ )
210
+ }
211
+
212
+ function EditorScreen() {
213
+ const { setOptions } = useScreen()
214
+ const [dirty, setDirty] = useState(false)
215
+
216
+ useEffect(() => {
217
+ setOptions({
218
+ headerRight: dirty ? (
219
+ <Button variant="soft" size="1" onClick={() => setDirty(false)}>Save</Button>
220
+ ) : null,
221
+ })
222
+ }, [dirty])
223
+
224
+ return (
225
+ <Extension.Content>
226
+ <Text size="2" color="gray">
227
+ {dirty ? 'You have unsaved changes.' : 'No changes yet.'}
228
+ </Text>
229
+ {!dirty && (
230
+ <Button variant="soft" size="2" onClick={() => setDirty(true)}>
231
+ Make a change
232
+ </Button>
233
+ )}
234
+ </Extension.Content>
235
+ )
236
+ }
237
+
238
+ function SettingsScreen() {
239
+ const { stack } = useNavigation()
240
+
241
+ return (
242
+ <Extension.Content>
243
+ <Text size="2" weight="medium">Navigation Stack</Text>
244
+ <Flex direction="column" gap="1">
245
+ {stack.map((entry, i) => (
246
+ <Flex key={i} align="center" gap="2">
247
+ <Badge variant="soft" size="1">{i}</Badge>
248
+ <Text size="1">{entry.name}</Text>
249
+ </Flex>
250
+ ))}
251
+ </Flex>
252
+ </Extension.Content>
253
+ )
254
+ }
255
+
256
+ export const NavigatorFull = {
257
+ name: 'Navigator (Multi-Screen)',
258
+ render: () => (
259
+ <Extension moises={mockMoises} initialScreen="home" animated>
260
+ <Extension.Screen name="home" title="Navigator Demo" component={HomeScreen}
261
+ headerRight={
262
+ <IconButton variant="ghost" color="gray" size="1">
263
+ <DotsVerticalIcon width={16} />
264
+ </IconButton>
265
+ }
266
+ />
267
+ <Extension.Screen name="detail" title="Detail" component={DetailScreen} />
268
+ <Extension.Screen name="editor" title="Editor" component={EditorScreen} />
269
+ <Extension.Screen name="settings" title="Settings" component={SettingsScreen} />
270
+ </Extension>
271
+ ),
272
+ }
273
+
274
+ // ---------------------------------------------------------------------------
275
+ // Navigator — minimal two-screen example
276
+ // ---------------------------------------------------------------------------
277
+
278
+ function ListScreen() {
279
+ const { push } = useNavigation()
280
+
281
+ return (
282
+ <Extension.Content>
283
+ <Text size="2" color="gray">A minimal two-screen navigator.</Text>
284
+ <Button variant="soft" size="2" onClick={() => push('about')}>
285
+ Go to About
286
+ </Button>
287
+ </Extension.Content>
288
+ )
289
+ }
290
+
291
+ function AboutScreen() {
292
+ return (
293
+ <Extension.Content>
294
+ <Text size="2">This is the about screen. Press the back arrow to return.</Text>
295
+ </Extension.Content>
296
+ )
297
+ }
298
+
299
+ export const NavigatorMinimal = {
300
+ name: 'Navigator (Minimal)',
301
+ render: () => (
302
+ <Extension moises={mockMoises} initialScreen="list" animated>
303
+ <Extension.Screen name="list" title="Home" component={ListScreen} />
304
+ <Extension.Screen name="about" title="About" component={AboutScreen} />
305
+ </Extension>
306
+ ),
307
+ }
308
+
309
+ // ---------------------------------------------------------------------------
310
+ // Navigator — dynamic header via setOptions
311
+ // ---------------------------------------------------------------------------
312
+
313
+ function CounterScreen() {
314
+ const { setOptions } = useScreen()
315
+ const [count, setCount] = useState(0)
316
+
317
+ useEffect(() => {
318
+ setOptions({
319
+ title: `Count: ${count}`,
320
+ headerRight: (
321
+ <Button variant="soft" size="1" onClick={() => setCount(0)}>Reset</Button>
322
+ ),
323
+ })
324
+ }, [count])
325
+
326
+ return (
327
+ <Extension.Content>
328
+ <Button variant="soft" size="2" onClick={() => setCount((c) => c + 1)}>
329
+ Increment
330
+ </Button>
331
+ </Extension.Content>
332
+ )
333
+ }
334
+
335
+ export const DynamicHeader = {
336
+ name: 'Navigator (Dynamic Header)',
337
+ render: () => (
338
+ <Extension moises={mockMoises} initialScreen="counter">
339
+ <Extension.Screen name="counter" title="Count: 0" component={CounterScreen} />
340
+ </Extension>
341
+ ),
342
+ }
343
+
344
+ // ---------------------------------------------------------------------------
345
+ // Navigator — custom close handler
346
+ // ---------------------------------------------------------------------------
347
+
348
+ function CloseInfoScreen() {
349
+ return (
350
+ <Extension.Content>
351
+ <Text size="2">The close button on this screen triggers a custom handler instead of `moises.extension.close()`.</Text>
352
+ </Extension.Content>
353
+ )
354
+ }
355
+
356
+ export const CustomClose = {
357
+ name: 'Navigator (Custom Close)',
358
+ render: () => (
359
+ <Extension moises={mockMoises} initialScreen="info">
360
+ <Extension.Screen
361
+ name="info"
362
+ title="Custom Close"
363
+ component={CloseInfoScreen}
364
+ onClose={() => console.log('custom onClose handler')}
365
+ />
366
+ </Extension>
367
+ ),
368
+ }
@@ -18,11 +18,19 @@ export const ProductsList = ({
18
18
  align="center"
19
19
  px="3"
20
20
  py="2"
21
+ role="button"
22
+ tabIndex={0}
21
23
  className={classNames(styles.navItem, {
22
24
  [styles.navItemSelected]: isSelected,
23
25
  [styles.collapsed]: collapsed,
24
26
  })}
25
27
  onClick={() => onProductClick?.(product.id, product)}
28
+ onKeyDown={(e) => {
29
+ if (e.key === 'Enter' || e.key === ' ') {
30
+ e.preventDefault()
31
+ onProductClick?.(product.id, product)
32
+ }
33
+ }}
26
34
  >
27
35
  {product.icon && (
28
36
  <div className={styles.navItemIcon}>{product.icon}</div>
@@ -63,6 +63,11 @@
63
63
  color: var(--neutral-alpha-12);
64
64
  }
65
65
 
66
+ .navItem:focus-visible {
67
+ outline: 2px solid var(--neutral-alpha-8);
68
+ outline-offset: -3px;
69
+ }
70
+
66
71
  .navItemSelected {
67
72
  background-color: var(--neutral-alpha-3);
68
73
  }
@@ -16,6 +16,8 @@ export function MenuTrigger({ className, user, collapsed, ...props }) {
16
16
  }
17
17
  return (
18
18
  <Flex
19
+ role="button"
20
+ tabIndex={0}
19
21
  onMouseEnter={handleMouseEnter}
20
22
  onMouseLeave={handleMouseLeave}
21
23
  className={classNames(styles.userProfile, { [styles.collapsed]: collapsed }, className)}
@@ -3,6 +3,11 @@
3
3
  width: 100%;
4
4
  }
5
5
 
6
+ .userProfile:focus-visible {
7
+ outline: 2px solid var(--neutral-alpha-8);
8
+ outline-offset: -3px;
9
+ }
10
+
6
11
  .userProfileInner {
7
12
  display: flex;
8
13
  align-items: center;
@@ -69,7 +69,11 @@ export const Select = ({
69
69
  </Text>
70
70
  ) : undefined}
71
71
  </SelectRadix.Trigger>
72
- <SelectRadix.Content position="popper" style={{ height: maxHeight }}>
72
+ <SelectRadix.Content
73
+ position="popper"
74
+ className={styles.selectContent}
75
+ style={{ height: maxHeight }}
76
+ >
73
77
  <SelectRadix.Group>
74
78
  {items.map((item) =>
75
79
  item.type === 'separator' ? (
@@ -1,3 +1,70 @@
1
+ /* Select content popover animation */
2
+ .selectContent {
3
+ animation-duration: 400ms;
4
+ animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
5
+ will-change: transform, opacity;
6
+ }
7
+
8
+ .selectContent[data-side='top'] {
9
+ animation-name: slideDownAndFade;
10
+ }
11
+
12
+ .selectContent[data-side='right'] {
13
+ animation-name: slideLeftAndFade;
14
+ }
15
+
16
+ .selectContent[data-side='bottom'] {
17
+ animation-name: slideUpAndFade;
18
+ }
19
+
20
+ .selectContent[data-side='left'] {
21
+ animation-name: slideRightAndFade;
22
+ }
23
+
24
+ @keyframes slideUpAndFade {
25
+ from {
26
+ opacity: 0;
27
+ transform: translateY(2px);
28
+ }
29
+ to {
30
+ opacity: 1;
31
+ transform: translateY(0);
32
+ }
33
+ }
34
+
35
+ @keyframes slideRightAndFade {
36
+ from {
37
+ opacity: 0;
38
+ transform: translateX(-2px);
39
+ }
40
+ to {
41
+ opacity: 1;
42
+ transform: translateX(0);
43
+ }
44
+ }
45
+
46
+ @keyframes slideDownAndFade {
47
+ from {
48
+ opacity: 0;
49
+ transform: translateY(-2px);
50
+ }
51
+ to {
52
+ opacity: 1;
53
+ transform: translateY(0);
54
+ }
55
+ }
56
+
57
+ @keyframes slideLeftAndFade {
58
+ from {
59
+ opacity: 0;
60
+ transform: translateX(2px);
61
+ }
62
+ to {
63
+ opacity: 1;
64
+ transform: translateX(0);
65
+ }
66
+ }
67
+
1
68
  .selectTrigger.soft:focus-visible,
2
69
  .selectTrigger.ghost:focus-visible {
3
70
  outline: none;
@@ -17,6 +17,7 @@ export const SetlistItem = ({
17
17
  onClick,
18
18
  className,
19
19
  style,
20
+ avatarStyle,
20
21
  avatar,
21
22
  text,
22
23
  subtitle,
@@ -50,6 +51,8 @@ export const SetlistItem = ({
50
51
  <Flex
51
52
  gap="3"
52
53
  align="center"
54
+ role="button"
55
+ tabIndex={0}
53
56
  onClick={onClick}
54
57
  className={classNames(styles.newSetlistItem, className, {
55
58
  [styles.navItemSelected]: isSelected,
@@ -58,6 +61,12 @@ export const SetlistItem = ({
58
61
  })}
59
62
  onMouseEnter={handleMouseEnter}
60
63
  onMouseLeave={handleMouseLeave}
64
+ onKeyDown={(e) => {
65
+ if (e.key === 'Enter' || e.key === ' ') {
66
+ e.preventDefault()
67
+ onClick?.()
68
+ }
69
+ }}
61
70
  style={style}
62
71
  >
63
72
  <Flex
@@ -68,13 +77,14 @@ export const SetlistItem = ({
68
77
  })}
69
78
  >
70
79
  {avatar && (
71
- <div className={styles.avatarSetlist}>
80
+ <div className={styles.avatarSetlist} style={avatarStyle}>
72
81
  {typeof avatar === 'string' ? (
73
82
  <Avatar
74
83
  src={avatar}
75
84
  fallback={<SetlistIcon width={16} height={16} />}
76
- size="3"
85
+ // size="3"
77
86
  radius="small"
87
+ style={avatarStyle}
78
88
  />
79
89
  ) : (
80
90
  avatar
@@ -141,9 +151,11 @@ export const SetlistList = ({
141
151
  }) => {
142
152
  const [openSetlistMenuId, setOpenSetlistMenuId] = useState(null)
143
153
  const [isHoveredWhenCollapsed, setIsHoveredWhenCollapsed] = useState(false)
154
+ const [isFullyCollapsed, setIsFullyCollapsed] = useState(false)
144
155
  const hoverTimeoutRef = useRef(null)
156
+ const collapseCenterTimeoutRef = useRef(null)
145
157
  const collapsedItemHeight = 44
146
- const collapsedVisibleOffset = 4
158
+ const collapsedVisibleOffset = 8
147
159
  const maxCollapsedItems = 4
148
160
  const collapsedNewItemOffset = collapsed && onNewSetlistClick ? 1 : 0
149
161
  const showCollapsedStack = collapsed && !isHoveredWhenCollapsed
@@ -170,6 +182,26 @@ export const SetlistList = ({
170
182
  }, 180)
171
183
  }
172
184
 
185
+ useEffect(() => {
186
+ if (showCollapsedStack) {
187
+ collapseCenterTimeoutRef.current = setTimeout(() => {
188
+ setIsFullyCollapsed(true)
189
+ collapseCenterTimeoutRef.current = null
190
+ }, 200)
191
+ } else {
192
+ setIsFullyCollapsed(false)
193
+ if (collapseCenterTimeoutRef.current) {
194
+ clearTimeout(collapseCenterTimeoutRef.current)
195
+ collapseCenterTimeoutRef.current = null
196
+ }
197
+ }
198
+ return () => {
199
+ if (collapseCenterTimeoutRef.current) {
200
+ clearTimeout(collapseCenterTimeoutRef.current)
201
+ }
202
+ }
203
+ }, [showCollapsedStack])
204
+
173
205
  useEffect(() => {
174
206
  return () => {
175
207
  if (hoverTimeoutRef.current) {
@@ -200,7 +232,9 @@ export const SetlistList = ({
200
232
  </div>
201
233
  )
202
234
 
203
- const getCollapsedStackStyle = (index) => {
235
+ const collapsedStackAvatarSizes = ['38px', '37px', '36px', '35px']
236
+
237
+ const getCollapsedStackStyle = (index, setlist) => {
204
238
  if (!collapsed) return undefined
205
239
  if (!showCollapsedStack) {
206
240
  return {
@@ -211,6 +245,14 @@ export const SetlistList = ({
211
245
  }
212
246
  const stackPosition = index + collapsedNewItemOffset
213
247
  const zIndex = setlists.length + collapsedNewItemOffset - stackPosition
248
+
249
+ const boxShadows = [
250
+ '0 3.84px 15.36px -7.68px var(--Overlays-Black-Alpha-2, rgba(0, 0, 0, 0.10)), 0 2.88px 11.52px -3.84px var(--Overlays-Black-Alpha-2, rgba(0, 0, 0, 0.10)), 0 1.92px 2.88px -1.92px var(--Overlays-Black-Alpha-3, rgba(0, 0, 0, 0.15))',
251
+ '0 3.686px 14.746px -7.373px var(--Overlays-Black-Alpha-2, rgba(0, 0, 0, 0.10)), 0 2.765px 11.059px -3.686px var(--Overlays-Black-Alpha-2, rgba(0, 0, 0, 0.10)), 0 1.843px 2.765px -1.843px var(--Overlays-Black-Alpha-3, rgba(0, 0, 0, 0.15))',
252
+ '0 3.539px 14.156px -7.078px var(--Overlays-Black-Alpha-2, rgba(0, 0, 0, 0.10)), 0 2.654px 10.617px -3.539px var(--Overlays-Black-Alpha-2, rgba(0, 0, 0, 0.10)), 0 1.769px 2.654px -1.769px var(--Overlays-Black-Alpha-3, rgba(0, 0, 0, 0.15))',
253
+ '0 3.401px 13.603px -6.801px var(--Overlays-Black-Alpha-2, rgba(0, 0, 0, 0.10)), 0 2.551px 10.202px -3.401px var(--Overlays-Black-Alpha-2, rgba(0, 0, 0, 0.10)), 0 1.701px 2.551px -1.701px var(--Overlays-Black-Alpha-3, rgba(0, 0, 0, 0.15))',
254
+ ]
255
+
214
256
  return {
215
257
  position: 'relative',
216
258
  marginTop:
@@ -218,6 +260,7 @@ export const SetlistList = ({
218
260
  ? 0
219
261
  : -(collapsedItemHeight - collapsedVisibleOffset),
220
262
  zIndex,
263
+ boxShadow: boxShadows[index],
221
264
  }
222
265
  }
223
266
 
@@ -239,6 +282,7 @@ export const SetlistList = ({
239
282
  direction="column"
240
283
  className={classNames(styles.setlistsContent, {
241
284
  [styles.collapsedStack]: showCollapsedStack,
285
+ [styles.collapsedStackCentered]: isFullyCollapsed,
242
286
  [styles.collapsedMask]: collapsed,
243
287
  })}
244
288
  >
@@ -283,6 +327,14 @@ export const SetlistList = ({
283
327
  setOpenSetlistMenuId(nextOpen ? setlist.id : null)
284
328
  }}
285
329
  avatar={setlist.icon || <SetlistIcon width={16} height={16} />}
330
+ avatarStyle={
331
+ showCollapsedStack
332
+ ? {
333
+ width: collapsedStackAvatarSizes[index],
334
+ height: collapsedStackAvatarSizes[index],
335
+ }
336
+ : undefined
337
+ }
286
338
  group={setlist.group}
287
339
  moises={setlist.moises}
288
340
  text={setlist.label}
@@ -294,7 +346,7 @@ export const SetlistList = ({
294
346
  [styles.collapsedStackItem]: showCollapsedStack,
295
347
  [styles.collapsedTransition]: collapsed,
296
348
  })}
297
- style={getCollapsedStackStyle(index)}
349
+ style={getCollapsedStackStyle(index, setlist)}
298
350
  />
299
351
  )
300
352
  })}