@moises.ai/design-system 3.10.15 → 3.10.17

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moises.ai/design-system",
3
- "version": "3.10.15",
3
+ "version": "3.10.17",
4
4
  "description": "Design System package based on @radix-ui/themes with custom defaults",
5
5
  "private": false,
6
6
  "type": "module",
@@ -11,6 +11,7 @@ export const BannerAnnouncement = ({
11
11
  badge,
12
12
  children,
13
13
  link,
14
+ onNavigate,
14
15
  alt,
15
16
  buttonColor,
16
17
  buttonText,
@@ -18,6 +19,7 @@ export const BannerAnnouncement = ({
18
19
  }) => {
19
20
  const navigateToLink = () => {
20
21
  window.open(link, '_self')
22
+ onNavigate?.()
21
23
  }
22
24
 
23
25
  const handleClose = useCallback(
@@ -55,6 +55,7 @@ function SetlistExpandButton({
55
55
  function NewSetlistButton({
56
56
  onClick,
57
57
  className,
58
+ style,
58
59
  collapsed = false,
59
60
  text = 'New Setlist',
60
61
  }) {
@@ -78,10 +79,10 @@ function NewSetlistButton({
78
79
  text={text}
79
80
  className={classNames(
80
81
  styles.newSetlistItemButton,
81
- styles.collapsedTransition,
82
82
  className,
83
83
  )}
84
84
  collapsed={collapsed}
85
+ style={style}
85
86
  />
86
87
  )
87
88
  }
@@ -307,66 +308,82 @@ export const SetlistList = ({
307
308
  onNewSetlistClick?.()
308
309
  if (isMobileDrawer) close()
309
310
  }
311
+
310
312
  const [isHoveredWhenCollapsed, setIsHoveredWhenCollapsed] = useState(false)
311
313
  const [isShrinking, setIsShrinking] = useState(false)
312
- const hoverTimeoutRef = useRef(null)
314
+ const [isExpanding, setIsExpanding] = useState(false)
315
+ const [isCollapseTransitioning, setIsCollapseTransitioning] = useState(false)
313
316
  const shrinkTimeoutRef = useRef(null)
317
+ const expandTimeoutRef = useRef(null)
314
318
  const hoverRegionRef = useRef(null)
315
- const shrinkDuration = 260
319
+ const prevCollapsedRef = useRef(collapsed)
320
+ const staggerBaseDelay = 50
321
+ const staggerItemDuration = 200
316
322
  const collapsedItemHeight = 44
317
323
  const collapsedVisibleOffset = 4
318
324
  const maxCollapsedItems = 4
319
325
  const collapsedNewItemOffset = collapsed && onNewSetlistClick ? 1 : 0
320
- const showCollapsedStack = collapsed && !isHoveredWhenCollapsed
321
- const visibleSetlists = showCollapsedStack
322
- ? setlists.slice(0, maxCollapsedItems)
323
- : setlists
326
+ const showCollapsedStack = collapsed && !isHoveredWhenCollapsed && !isCollapseTransitioning
327
+ const visibleSetlists = setlists
324
328
 
325
- const leaveCollapseDelay = 2750
329
+ const totalAnimatedItems = setlists.length + (onNewSetlistClick ? 1 : 0)
330
+ const staggerTotalDuration = staggerItemDuration + totalAnimatedItems * staggerBaseDelay
331
+
332
+ const expandItems = () => {
333
+ if (shrinkTimeoutRef.current) {
334
+ clearTimeout(shrinkTimeoutRef.current)
335
+ shrinkTimeoutRef.current = null
336
+ }
337
+ if (expandTimeoutRef.current) {
338
+ clearTimeout(expandTimeoutRef.current)
339
+ expandTimeoutRef.current = null
340
+ }
341
+ setIsShrinking(false)
342
+ setIsExpanding(true)
343
+ setIsHoveredWhenCollapsed(true)
344
+ expandTimeoutRef.current = setTimeout(() => {
345
+ setIsExpanding(false)
346
+ expandTimeoutRef.current = null
347
+ }, staggerTotalDuration)
348
+ }
326
349
 
327
350
  const handleMouseEnter = () => {
328
351
  if (!collapsed) return
329
- if (hoverTimeoutRef.current) {
330
- clearTimeout(hoverTimeoutRef.current)
331
- hoverTimeoutRef.current = null
332
- }
333
352
  if (shrinkTimeoutRef.current) {
334
353
  clearTimeout(shrinkTimeoutRef.current)
335
354
  shrinkTimeoutRef.current = null
336
355
  }
337
- setIsShrinking(false)
356
+ if (isShrinking) {
357
+ setIsShrinking(false)
358
+ } else if (!isHoveredWhenCollapsed) {
359
+ expandItems()
360
+ }
338
361
  }
339
362
 
340
363
  const handleMouseLeave = () => {
341
364
  if (!collapsed) return
342
365
  if (!isHoveredWhenCollapsed) return
343
- if (hoverTimeoutRef.current) {
344
- clearTimeout(hoverTimeoutRef.current)
366
+ if (expandTimeoutRef.current) {
367
+ clearTimeout(expandTimeoutRef.current)
368
+ expandTimeoutRef.current = null
345
369
  }
346
- hoverTimeoutRef.current = setTimeout(() => {
347
- hoverTimeoutRef.current = null
348
- setIsShrinking(true)
349
- shrinkTimeoutRef.current = setTimeout(() => {
350
- shrinkTimeoutRef.current = null
351
- setIsHoveredWhenCollapsed(false)
352
- setIsShrinking(false)
353
- }, shrinkDuration)
354
- }, leaveCollapseDelay)
370
+ setIsExpanding(false)
371
+ setIsShrinking(true)
372
+ shrinkTimeoutRef.current = setTimeout(() => {
373
+ shrinkTimeoutRef.current = null
374
+ setIsHoveredWhenCollapsed(false)
375
+ setIsShrinking(false)
376
+ }, staggerTotalDuration)
355
377
  }
356
378
 
357
379
  const handleSetlistIconClick = (e) => {
358
380
  if (!collapsed) return
359
381
  e.stopPropagation()
360
- if (hoverTimeoutRef.current) {
361
- clearTimeout(hoverTimeoutRef.current)
362
- hoverTimeoutRef.current = null
363
- }
364
- setIsShrinking(false)
365
- setIsHoveredWhenCollapsed(true)
382
+ expandItems()
366
383
  }
367
384
 
368
385
  const handleFocus = () => {
369
- if (collapsed) setIsHoveredWhenCollapsed(true)
386
+ if (collapsed && !isHoveredWhenCollapsed) expandItems()
370
387
  }
371
388
 
372
389
  const handleBlur = () => {
@@ -380,10 +397,47 @@ export const SetlistList = ({
380
397
  }, 0)
381
398
  }
382
399
 
400
+ if (prevCollapsedRef.current !== collapsed) {
401
+ const wasCollapsed = prevCollapsedRef.current
402
+ prevCollapsedRef.current = collapsed
403
+
404
+ if (collapsed && !wasCollapsed) {
405
+ setIsCollapseTransitioning(true)
406
+ setIsExpanding(false)
407
+ setIsShrinking(true)
408
+ } else if (!collapsed && wasCollapsed) {
409
+ setIsHoveredWhenCollapsed(false)
410
+ setIsCollapseTransitioning(true)
411
+ setIsShrinking(false)
412
+ setIsExpanding(true)
413
+ }
414
+ }
415
+
416
+ useEffect(() => {
417
+ if (!isCollapseTransitioning) return
418
+
419
+ if (shrinkTimeoutRef.current) {
420
+ clearTimeout(shrinkTimeoutRef.current)
421
+ shrinkTimeoutRef.current = null
422
+ }
423
+ if (expandTimeoutRef.current) {
424
+ clearTimeout(expandTimeoutRef.current)
425
+ expandTimeoutRef.current = null
426
+ }
427
+
428
+ const id = setTimeout(() => {
429
+ setIsCollapseTransitioning(false)
430
+ setIsShrinking(false)
431
+ setIsExpanding(false)
432
+ }, staggerTotalDuration)
433
+
434
+ return () => clearTimeout(id)
435
+ }, [isCollapseTransitioning, staggerTotalDuration])
436
+
383
437
  useEffect(() => {
384
438
  return () => {
385
- if (hoverTimeoutRef.current) clearTimeout(hoverTimeoutRef.current)
386
439
  if (shrinkTimeoutRef.current) clearTimeout(shrinkTimeoutRef.current)
440
+ if (expandTimeoutRef.current) clearTimeout(expandTimeoutRef.current)
387
441
  }
388
442
  }, [])
389
443
 
@@ -417,6 +471,30 @@ export const SetlistList = ({
417
471
  }
418
472
  }
419
473
 
474
+ const isStaggerActive = (collapsed && !showCollapsedStack) || isCollapseTransitioning
475
+ const itemCollapsed = collapsed || isCollapseTransitioning
476
+
477
+ const getStaggerStyle = (itemIndex) => {
478
+ if (!isStaggerActive) return undefined
479
+ if (isShrinking) {
480
+ const outY = -(itemIndex * (collapsedItemHeight - collapsedVisibleOffset))
481
+ return {
482
+ animationDelay: `${itemIndex * staggerBaseDelay}ms`,
483
+ '--stagger-out-y': `${outY}px`,
484
+ zIndex: totalAnimatedItems - itemIndex,
485
+ }
486
+ }
487
+ if (isExpanding) {
488
+ const inY = -(itemIndex * (collapsedItemHeight - collapsedVisibleOffset))
489
+ return {
490
+ animationDelay: `${(totalAnimatedItems - 1 - itemIndex) * staggerBaseDelay}ms`,
491
+ '--stagger-in-y': `${inY}px`,
492
+ zIndex: totalAnimatedItems - itemIndex,
493
+ }
494
+ }
495
+ return undefined
496
+ }
497
+
420
498
  return (
421
499
  <ScrollArea
422
500
  type="scroll"
@@ -439,7 +517,6 @@ export const SetlistList = ({
439
517
  className={classNames(styles.setlistsContent, {
440
518
  [styles.collapsedStack]: showCollapsedStack,
441
519
  [styles.collapsedMask]: collapsed,
442
- [styles.collapsedShrinking]: isShrinking,
443
520
  })}
444
521
  >
445
522
  {onNewSetlistClick &&
@@ -458,8 +535,13 @@ export const SetlistList = ({
458
535
  ) : (
459
536
  <NewSetlistButton
460
537
  onClick={handleNewSetlistClick}
461
- className={styles.collapsedTransition}
462
- collapsed={collapsed}
538
+ className={classNames({
539
+ [styles.staggerItem]: isStaggerActive,
540
+ [styles.staggerAnimateIn]: isStaggerActive && isExpanding,
541
+ [styles.staggerAnimateOut]: isStaggerActive && isShrinking,
542
+ })}
543
+ style={getStaggerStyle(0)}
544
+ collapsed={itemCollapsed}
463
545
  text={newSetlistButtonText}
464
546
  />
465
547
  ))}
@@ -499,13 +581,19 @@ export const SetlistList = ({
499
581
  text={setlist.label}
500
582
  subtitle={setlist.subtitle}
501
583
  dropdownMenuOptions={setlist.dropdownMenuOptions}
502
- collapsed={collapsed}
584
+ collapsed={itemCollapsed}
503
585
  isMobile={isMobile}
504
586
  className={classNames({
505
587
  [styles.collapsedStackItem]: showCollapsedStack,
506
- [styles.collapsedTransition]: collapsed,
588
+ [styles.collapsedTransition]: collapsed && showCollapsedStack,
589
+ [styles.staggerItem]: isStaggerActive,
590
+ [styles.staggerAnimateIn]: isStaggerActive && isExpanding,
591
+ [styles.staggerAnimateOut]: isStaggerActive && isShrinking,
507
592
  })}
508
- style={getCollapsedStackStyle(index)}
593
+ style={{
594
+ ...getCollapsedStackStyle(index),
595
+ ...getStaggerStyle(index + collapsedNewItemOffset),
596
+ }}
509
597
  />
510
598
  )
511
599
  return collapsed && !showCollapsedStack ? (
@@ -298,8 +298,7 @@ sectionTitle {
298
298
  transition: max-height 260ms ease-in-out;
299
299
  }
300
300
 
301
- .collapsedMask.collapsedStack,
302
- .collapsedMask.collapsedShrinking {
301
+ .collapsedMask.collapsedStack {
303
302
  overflow: hidden;
304
303
  max-height: 120px;
305
304
  }
@@ -312,6 +311,35 @@ sectionTitle {
312
311
  transition: margin-top 260ms ease-in-out;
313
312
  }
314
313
 
314
+ @keyframes staggerIn {
315
+ from {
316
+ transform: translateY(var(--stagger-in-y, 0));
317
+ }
318
+ to {
319
+ transform: translateY(0);
320
+ }
321
+ }
322
+
323
+ @keyframes staggerOut {
324
+ to {
325
+ transform: translateY(var(--stagger-out-y, 0));
326
+ }
327
+ }
328
+
329
+ .staggerItem {
330
+ opacity: 1;
331
+ transform: translateY(0);
332
+ transition: margin-top 260ms ease-in-out;
333
+ }
334
+
335
+ .staggerAnimateIn {
336
+ animation: staggerIn 200ms ease-out both;
337
+ }
338
+
339
+ .staggerAnimateOut {
340
+ animation: staggerOut 200ms ease-out both;
341
+ }
342
+
315
343
  .contentInner {
316
344
  gap: 12px;
317
345
  flex: 1;