@shohojdhara/atomix 0.2.5 → 0.2.7

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +3 -3
  3. package/dist/atomix.css +77 -9
  4. package/dist/atomix.min.css +1 -1
  5. package/dist/index.d.ts +202 -10
  6. package/dist/index.esm.js +599 -170
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/index.js +608 -170
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.min.js +1 -1
  11. package/dist/index.min.js.map +1 -1
  12. package/dist/themes/applemix.css +77 -9
  13. package/dist/themes/applemix.min.css +1 -1
  14. package/dist/themes/boomdevs.css +77 -9
  15. package/dist/themes/boomdevs.min.css +1 -1
  16. package/dist/themes/esrar.css +77 -9
  17. package/dist/themes/esrar.min.css +1 -1
  18. package/dist/themes/flashtrade.css +77 -9
  19. package/dist/themes/flashtrade.min.css +1 -1
  20. package/dist/themes/mashroom.css +77 -9
  21. package/dist/themes/mashroom.min.css +1 -1
  22. package/dist/themes/shaj-default.css +77 -9
  23. package/dist/themes/shaj-default.min.css +1 -1
  24. package/package.json +1 -1
  25. package/src/components/AtomixGlass/AtomixGlass.tsx +0 -2
  26. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +0 -1
  27. package/src/components/Button/Button.stories.tsx +25 -0
  28. package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +121 -11
  29. package/src/components/ColorModeToggle/ColorModeToggle.tsx +146 -45
  30. package/src/components/ColorModeToggle/index.ts +1 -1
  31. package/src/components/Hero/Hero.stories.tsx +297 -0
  32. package/src/components/Hero/Hero.tsx +79 -0
  33. package/src/components/{Tab/Tab.stories.tsx → Tabs/Tabs.stories.tsx} +9 -9
  34. package/src/components/{Tab/Tab.tsx → Tabs/Tabs.tsx} +7 -7
  35. package/src/components/Tabs/index.ts +2 -0
  36. package/src/components/index.ts +12 -2
  37. package/src/lib/composables/useHero.ts +33 -4
  38. package/src/lib/composables/useHeroBackgroundSlider.ts +228 -0
  39. package/src/lib/constants/components.ts +7 -1
  40. package/src/lib/types/components.ts +98 -0
  41. package/src/styles/06-components/_components.atomix-glass.scss +4 -3
  42. package/src/styles/06-components/_components.color-mode-toggle.scss +43 -6
  43. package/src/styles/06-components/_components.hero.scss +51 -1
  44. package/src/components/Tab/index.ts +0 -2
@@ -100,6 +100,10 @@ const meta = {
100
100
  control: 'object',
101
101
  description: 'Video background options',
102
102
  },
103
+ backgroundSlider: {
104
+ control: 'object',
105
+ description: 'Background slider configuration with multiple images/videos',
106
+ },
103
107
  },
104
108
  } satisfies Meta<typeof Hero>;
105
109
 
@@ -345,3 +349,296 @@ export const VideoBackgroundWithImage: Story = {
345
349
  imageAlt: 'Product showcase',
346
350
  },
347
351
  };
352
+
353
+ /**
354
+ * Hero with background image slider (fade transition)
355
+ */
356
+ export const WithBackgroundSlider: Story = {
357
+ args: {
358
+ title: 'Dynamic Background Slider',
359
+ subtitle: 'Multiple Images with Fade Transition',
360
+ text: 'This hero features a background slider with multiple images that automatically transition using a smooth fade effect. Perfect for showcasing multiple products or features.',
361
+ alignment: 'center',
362
+ showOverlay: true,
363
+ actions: showcaseActionButtons,
364
+ contentWidth: '800px',
365
+ backgroundSlider: {
366
+ slides: [
367
+ {
368
+ type: 'image',
369
+ src: 'https://picsum.photos/id/1015/1920/1080',
370
+ alt: 'Mountain landscape',
371
+ },
372
+ {
373
+ type: 'image',
374
+ src: 'https://picsum.photos/id/1018/1920/1080',
375
+ alt: 'Forest scene',
376
+ },
377
+ {
378
+ type: 'image',
379
+ src: 'https://picsum.photos/id/1025/1920/1080',
380
+ alt: 'Ocean view',
381
+ },
382
+ {
383
+ type: 'image',
384
+ src: 'https://picsum.photos/id/1035/1920/1080',
385
+ alt: 'City skyline',
386
+ },
387
+ ],
388
+ autoplay: {
389
+ delay: 3000,
390
+ pauseOnHover: false,
391
+ },
392
+ loop: true,
393
+ transition: 'fade',
394
+ transitionDuration: 1000,
395
+ },
396
+ },
397
+ };
398
+
399
+ /**
400
+ * Hero with background slider (mixed images and videos)
401
+ */
402
+ export const WithMixedMediaSlider: Story = {
403
+ args: {
404
+ title: 'Mixed Media Background Slider',
405
+ subtitle: 'Images & Videos Combined',
406
+ text: 'This hero demonstrates a background slider that seamlessly transitions between images and videos, creating a rich, dynamic visual experience.',
407
+ alignment: 'center',
408
+ showOverlay: true,
409
+ actions: showcaseActionButtons,
410
+ contentWidth: '800px',
411
+ backgroundSlider: {
412
+ slides: [
413
+ {
414
+ type: 'image',
415
+ src: 'https://picsum.photos/id/1015/1920/1080',
416
+ alt: 'Mountain landscape',
417
+ },
418
+ {
419
+ type: 'video',
420
+ src: 'https://cdn.pixabay.com/video/2021/02/20/65772-515379427_large.mp4',
421
+ videoOptions: {
422
+ autoplay: true,
423
+ loop: true,
424
+ muted: true,
425
+ posterUrl: 'https://picsum.photos/id/1018/1920/1080',
426
+ },
427
+ },
428
+ {
429
+ type: 'image',
430
+ src: 'https://picsum.photos/id/1025/1920/1080',
431
+ alt: 'Ocean view',
432
+ },
433
+ {
434
+ type: 'video',
435
+ src: 'https://cdn.pixabay.com/video/2023/11/18/189639-886016299_large.mp4',
436
+ videoOptions: {
437
+ autoplay: true,
438
+ loop: true,
439
+ muted: true,
440
+ posterUrl: 'https://picsum.photos/id/1035/1920/1080',
441
+ },
442
+ },
443
+ ],
444
+ autoplay: {
445
+ delay: 4000,
446
+ pauseOnHover: false,
447
+ },
448
+ loop: true,
449
+ transition: 'fade',
450
+ transitionDuration: 1500,
451
+ },
452
+ },
453
+ };
454
+
455
+ /**
456
+ * Hero with background slider (fast transitions)
457
+ */
458
+ export const WithFastSlider: Story = {
459
+ args: {
460
+ title: 'Fast-Paced Background Slider',
461
+ subtitle: 'Quick Transitions',
462
+ text: 'This slider uses faster transition times and shorter delays for a more dynamic, energetic feel.',
463
+ alignment: 'center',
464
+ showOverlay: true,
465
+ actions: primaryActionButtons,
466
+ contentWidth: '800px',
467
+ backgroundSlider: {
468
+ slides: [
469
+ {
470
+ type: 'image',
471
+ src: 'https://picsum.photos/id/106/1920/1080',
472
+ alt: 'Abstract art',
473
+ },
474
+ {
475
+ type: 'image',
476
+ src: 'https://picsum.photos/id/107/1920/1080',
477
+ alt: 'Nature scene',
478
+ },
479
+ {
480
+ type: 'image',
481
+ src: 'https://picsum.photos/id/108/1920/1080',
482
+ alt: 'Urban landscape',
483
+ },
484
+ ],
485
+ autoplay: {
486
+ delay: 2000,
487
+ pauseOnHover: false,
488
+ },
489
+ loop: true,
490
+ transition: 'fade',
491
+ transitionDuration: 500,
492
+ },
493
+ },
494
+ };
495
+
496
+ /**
497
+ * Hero with background slider (pause on hover)
498
+ */
499
+ export const WithPauseOnHoverSlider: Story = {
500
+ args: {
501
+ title: 'Interactive Background Slider',
502
+ subtitle: 'Pause on Hover',
503
+ text: 'Hover over this hero to pause the slider. Move your mouse away to resume. Perfect for giving users control over the experience.',
504
+ alignment: 'center',
505
+ showOverlay: true,
506
+ actions: showcaseActionButtons,
507
+ contentWidth: '800px',
508
+ backgroundSlider: {
509
+ slides: [
510
+ {
511
+ type: 'image',
512
+ src: 'https://picsum.photos/id/1015/1920/1080',
513
+ alt: 'Mountain landscape',
514
+ },
515
+ {
516
+ type: 'image',
517
+ src: 'https://picsum.photos/id/1018/1920/1080',
518
+ alt: 'Forest scene',
519
+ },
520
+ {
521
+ type: 'image',
522
+ src: 'https://picsum.photos/id/1025/1920/1080',
523
+ alt: 'Ocean view',
524
+ },
525
+ {
526
+ type: 'image',
527
+ src: 'https://picsum.photos/id/1035/1920/1080',
528
+ alt: 'City skyline',
529
+ },
530
+ {
531
+ type: 'image',
532
+ src: 'https://picsum.photos/id/1041/1920/1080',
533
+ alt: 'Desert landscape',
534
+ },
535
+ ],
536
+ autoplay: {
537
+ delay: 3000,
538
+ pauseOnHover: true,
539
+ },
540
+ loop: true,
541
+ transition: 'fade',
542
+ transitionDuration: 1000,
543
+ },
544
+ },
545
+ };
546
+
547
+ /**
548
+ * Hero with background slider and glass effect
549
+ */
550
+ export const SliderWithGlassEffect: Story = {
551
+ args: {
552
+ title: 'Slider with Glass Effect',
553
+ subtitle: 'Best of Both Worlds',
554
+ text: 'Combine the dynamic background slider with the elegant glass effect for a truly modern, sophisticated hero section.',
555
+ alignment: 'center',
556
+ showOverlay: true,
557
+ glass: true,
558
+ actions: showcaseActionButtons,
559
+ contentWidth: '800px',
560
+ backgroundSlider: {
561
+ slides: [
562
+ {
563
+ type: 'video',
564
+ src: 'https://cdn.pixabay.com/video/2021/02/20/65772-515379427_large.mp4',
565
+ videoOptions: {
566
+ autoplay: true,
567
+ loop: true,
568
+ muted: true,
569
+ posterUrl: 'https://picsum.photos/id/1018/1920/1080',
570
+ },
571
+ },
572
+ {
573
+ type: 'video',
574
+ src: 'https://cdn.pixabay.com/video/2020/11/09/56026-478239201_large.mp4',
575
+ videoOptions: {
576
+ autoplay: true,
577
+ loop: true,
578
+ muted: true,
579
+ posterUrl: 'https://picsum.photos/id/1018/1920/1080',
580
+ },
581
+ },
582
+ {
583
+ type: 'video',
584
+ src: 'https://cdn.pixabay.com/video/2023/11/18/189639-886016299_large.mp4',
585
+ videoOptions: {
586
+ autoplay: true,
587
+ loop: true,
588
+ muted: true,
589
+ posterUrl: 'https://picsum.photos/id/1018/1920/1080',
590
+ },
591
+ },
592
+ ],
593
+ autoplay: {
594
+ delay: 30000,
595
+ pauseOnHover: false,
596
+ },
597
+ loop: true,
598
+ transition: 'fade',
599
+ transitionDuration: 1200,
600
+ },
601
+ },
602
+ };
603
+
604
+ /**
605
+ * Hero with background slider (full viewport height)
606
+ */
607
+ export const FullHeightSlider: Story = {
608
+ args: {
609
+ title: 'Full Height Background Slider',
610
+ subtitle: 'Immersive Experience',
611
+ text: 'This hero takes the full viewport height and features a background slider, creating an immersive, full-screen experience.',
612
+ alignment: 'center',
613
+ showOverlay: true,
614
+ fullViewportHeight: true,
615
+ actions: showcaseActionButtons,
616
+ contentWidth: '800px',
617
+ backgroundSlider: {
618
+ slides: [
619
+ {
620
+ type: 'image',
621
+ src: 'https://picsum.photos/id/1015/1920/1080',
622
+ alt: 'Mountain landscape',
623
+ },
624
+ {
625
+ type: 'image',
626
+ src: 'https://picsum.photos/id/1018/1920/1080',
627
+ alt: 'Forest scene',
628
+ },
629
+ {
630
+ type: 'image',
631
+ src: 'https://picsum.photos/id/1025/1920/1080',
632
+ alt: 'Ocean view',
633
+ },
634
+ ],
635
+ autoplay: {
636
+ delay: 4000,
637
+ pauseOnHover: false,
638
+ },
639
+ loop: true,
640
+ transition: 'fade',
641
+ transitionDuration: 1500,
642
+ },
643
+ },
644
+ };
@@ -30,6 +30,7 @@ export const Hero: React.FC<HeroProps> = ({
30
30
  loop: true,
31
31
  muted: true,
32
32
  },
33
+ backgroundSlider,
33
34
  }) => {
34
35
  const {
35
36
  generateHeroClassNames,
@@ -40,6 +41,8 @@ export const Hero: React.FC<HeroProps> = ({
40
41
  useGridLayout,
41
42
  heroRef,
42
43
  videoRef,
44
+ backgroundSlider: sliderHook,
45
+ hasBackgroundSlider,
43
46
  } = useHero({
44
47
  alignment,
45
48
  imageColSize,
@@ -52,6 +55,7 @@ export const Hero: React.FC<HeroProps> = ({
52
55
  parallax,
53
56
  parallaxIntensity,
54
57
  videoBackground,
58
+ backgroundSlider,
55
59
  });
56
60
 
57
61
  // Create custom style for hero element with content width if provided
@@ -82,6 +86,81 @@ export const Hero: React.FC<HeroProps> = ({
82
86
  };
83
87
 
84
88
  const renderBackground = () => {
89
+ // Render background slider if configured
90
+ if (hasBackgroundSlider && backgroundSlider && sliderHook) {
91
+ const { slides, transition = 'fade', transitionDuration = 1000 } = backgroundSlider;
92
+ const { currentIndex, slideRefs, videoRefs } = sliderHook;
93
+
94
+ // Determine transition class
95
+ let transitionClass = HERO.CLASSES.SLIDER_FADE;
96
+ if (transition === 'slide') {
97
+ transitionClass = HERO.CLASSES.SLIDER_SLIDE;
98
+ } else if (transition === 'custom') {
99
+ transitionClass = HERO.CLASSES.SLIDER_CUSTOM;
100
+ }
101
+
102
+ return (
103
+ <div
104
+ className={`${HERO.SELECTORS.SLIDER.replace('.', '')} ${transitionClass}`}
105
+ style={{
106
+ '--slider-transition-duration': `${transitionDuration}ms`,
107
+ } as React.CSSProperties}
108
+ onMouseEnter={() => {
109
+ if (backgroundSlider.autoplay?.pauseOnHover) {
110
+ sliderHook.pauseAutoplay();
111
+ }
112
+ }}
113
+ onMouseLeave={() => {
114
+ if (backgroundSlider.autoplay?.pauseOnHover) {
115
+ sliderHook.resumeAutoplay();
116
+ }
117
+ }}
118
+ >
119
+ {slides.map((slide, index) => {
120
+ const isActive = index === currentIndex;
121
+ const slideRef = slideRefs[index];
122
+ const videoRef = videoRefs[index];
123
+
124
+ return (
125
+ <div
126
+ key={index}
127
+ ref={slideRef}
128
+ className={`${HERO.SELECTORS.SLIDER_ITEM.replace('.', '')} ${
129
+ isActive ? HERO.CLASSES.SLIDER_ITEM_ACTIVE : ''
130
+ }`}
131
+ >
132
+ {slide.type === 'image' ? (
133
+ <img
134
+ src={slide.src}
135
+ alt={slide.alt || 'Background slide'}
136
+ className={HERO.SELECTORS.BG_IMAGE.replace('.', '')}
137
+ />
138
+ ) : (
139
+ <video
140
+ ref={videoRef as React.LegacyRef<HTMLVideoElement>}
141
+ className="c-hero__video"
142
+ autoPlay={slide.videoOptions?.autoplay !== false}
143
+ loop={slide.videoOptions?.loop !== false}
144
+ muted={slide.videoOptions?.muted !== false}
145
+ playsInline
146
+ poster={slide.videoOptions?.posterUrl}
147
+ >
148
+ <source
149
+ src={slide.src}
150
+ type={`video/${slide.src.split('.').pop() || 'mp4'}`}
151
+ />
152
+ Your browser does not support the video tag.
153
+ </video>
154
+ )}
155
+ </div>
156
+ );
157
+ })}
158
+ {showOverlay && <div className={HERO.SELECTORS.OVERLAY.replace('.', '')}></div>}
159
+ </div>
160
+ );
161
+ }
162
+
163
+ // Fall back to single background image/video
85
164
  if (!hasBackgroundImage && !videoBackground) return null;
86
165
 
87
166
  return (
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
2
  import { StoryFn, Meta } from '@storybook/react';
3
3
  import { fn } from '@storybook/test';
4
- import { Tab } from './Tab';
4
+ import { Tabs } from './Tabs';
5
5
 
6
6
  export default {
7
- title: 'Components/Tab',
8
- component: Tab,
7
+ title: 'Components/Tabs',
8
+ component: Tabs,
9
9
  argTypes: {
10
10
  activeIndex: {
11
11
  control: { type: 'number' },
@@ -16,11 +16,11 @@ export default {
16
16
  description: 'Enable glass morphism effect',
17
17
  },
18
18
  },
19
- } as Meta<typeof Tab>;
19
+ } as Meta<typeof Tabs>;
20
20
 
21
- const Template: StoryFn<typeof Tab> = args => (
21
+ const Template: StoryFn<typeof Tabs> = args => (
22
22
  <div style={{ maxWidth: '600px', margin: '0 auto', padding: '30px' }}>
23
- <Tab {...args} />
23
+ <Tabs {...args} />
24
24
  </div>
25
25
  );
26
26
 
@@ -164,7 +164,7 @@ export const Glass = {
164
164
  }}
165
165
  >
166
166
  <div style={{ width: '100%', maxWidth: '600px' }}>
167
- <Tab {...args} />
167
+ <Tabs {...args} />
168
168
  </div>
169
169
  </div>
170
170
  ),
@@ -211,8 +211,8 @@ export const GlassCustom = {
211
211
  }}
212
212
  >
213
213
  <div style={{ width: '100%', maxWidth: '600px' }}>
214
- <Tab {...args} />
214
+ <Tabs {...args} />
215
215
  </div>
216
216
  </div>
217
217
  ),
218
- };
218
+ };
@@ -3,7 +3,7 @@ import { TAB } from '../../lib/constants/components';
3
3
  import { AtomixGlass } from '../AtomixGlass/AtomixGlass';
4
4
  import { AtomixGlassProps } from '../../lib/types/components';
5
5
 
6
- export interface TabItemProps {
6
+ export interface TabsItemProps {
7
7
  /**
8
8
  * Label for the tab
9
9
  */
@@ -25,11 +25,11 @@ export interface TabItemProps {
25
25
  className?: string;
26
26
  }
27
27
 
28
- export interface TabProps {
28
+ export interface TabsProps {
29
29
  /**
30
30
  * Array of tab items
31
31
  */
32
- items: TabItemProps[];
32
+ items: TabsItemProps[];
33
33
 
34
34
  /**
35
35
  * Initial active tab index
@@ -59,9 +59,9 @@ export interface TabProps {
59
59
  }
60
60
 
61
61
  /**
62
- * Tab component for switching between different content panels
62
+ * Tabs component for switching between different content panels
63
63
  */
64
- export const Tab: React.FC<TabProps> = ({
64
+ export const Tabs: React.FC<TabsProps> = ({
65
65
  items,
66
66
  activeIndex = TAB.DEFAULTS.ACTIVE_INDEX,
67
67
  onTabChange,
@@ -139,6 +139,6 @@ export const Tab: React.FC<TabProps> = ({
139
139
  return tabContent;
140
140
  };
141
141
 
142
- Tab.displayName = 'Tab';
142
+ Tabs.displayName = 'Tabs';
143
143
 
144
- export default Tab;
144
+ export default Tabs;
@@ -0,0 +1,2 @@
1
+ export { Tabs } from './Tabs';
2
+ export type { TabsProps, TabsItemProps } from './Tabs';
@@ -10,6 +10,8 @@ export { default as Breadcrumb, type BreadcrumbProps } from './Breadcrumb/Breadc
10
10
  export { default as Button, type ButtonProps } from './Button/Button';
11
11
  export { default as Callout, type CalloutProps } from './Callout/Callout';
12
12
  export { default as Card, type CardProps } from './Card/Card';
13
+ // Card sub-components
14
+ export { default as ElevationCard, type ElevationCardProps } from './Card/ElevationCard';
13
15
  export {
14
16
  AnimatedChart,
15
17
  AreaChart,
@@ -29,7 +31,6 @@ export {
29
31
  ScatterChart,
30
32
  TreemapChart,
31
33
  WaterfallChart,
32
- type AnimatedChartProps,
33
34
  type AreaChartProps,
34
35
  type BarChartProps,
35
36
  type BubbleChartProps,
@@ -87,6 +88,9 @@ export { default as Textarea, type TextareaProps } from './Form/Textarea';
87
88
  export { default as Hero, type HeroProps } from './Hero/Hero';
88
89
  export { default as Icon, type IconProps } from './Icon/Icon';
89
90
  export { default as List, type ListProps } from './List/List';
91
+ // List sub-components
92
+ export { ListGroup } from './List/ListGroup';
93
+ export type { ListGroupProps } from '../lib/types/components';
90
94
  export { default as Messages, type MessagesProps } from './Messages/Messages';
91
95
  export { default as Modal, type ModalProps } from './Modal/Modal';
92
96
  export { default as Nav, type NavProps } from './Navigation/Nav/Nav';
@@ -101,6 +105,12 @@ export {
101
105
  default as SideMenuList,
102
106
  type SideMenuListProps,
103
107
  } from './Navigation/SideMenu/SideMenuList';
108
+ // Menu components
109
+ export { Menu, MenuItem, MenuDivider, type MenuProps, type MenuItemProps, type MenuDividerProps } from './Navigation/Menu/Menu';
110
+ export { MegaMenu, MegaMenuColumn, MegaMenuLink } from './Navigation/Menu/MegaMenu';
111
+ export type { MegaMenuProps, MegaMenuColumnProps, MegaMenuLinkProps } from '../lib/types/components';
112
+ // Navigation sub-components
113
+ export { NavDropdown, type NavDropdownProps } from './Navigation/Nav/NavDropdown';
104
114
  export { default as Pagination, type PaginationProps } from './Pagination/Pagination';
105
115
  export { default as PhotoViewer, type PhotoViewerProps } from './PhotoViewer/PhotoViewer';
106
116
  export { default as Popover, type PopoverProps } from './Popover/Popover';
@@ -112,7 +122,7 @@ export { default as SectionIntro, type SectionIntroProps } from './SectionIntro/
112
122
  export { Slider } from './Slider/Slider';
113
123
  export { default as Spinner, type SpinnerProps } from './Spinner/Spinner';
114
124
  export { default as Steps, type StepsProps } from './Steps/Steps';
115
- export { default as Tab, type TabProps } from './Tab/Tab';
125
+ export { default as Tabs, type TabsProps } from './Tabs/Tabs';
116
126
  export { default as Testimonial, type TestimonialProps } from './Testimonial/Testimonial';
117
127
  export { default as Todo, type TodoProps } from './Todo/Todo';
118
128
  export { default as Toggle, type ToggleProps } from './Toggle/Toggle';
@@ -1,6 +1,7 @@
1
1
  import { useEffect, useRef } from 'react';
2
2
  import { HeroProps, HeroAlignment } from '../types/components';
3
3
  import { HERO } from '../constants/components';
4
+ import { useHeroBackgroundSlider, UseHeroBackgroundSliderResult } from './useHeroBackgroundSlider';
4
5
 
5
6
  /**
6
7
  * Hero hook result interface
@@ -55,6 +56,16 @@ interface UseHeroResult {
55
56
  * Remove parallax effect
56
57
  */
57
58
  removeParallaxEffect: (element: HTMLElement) => void;
59
+
60
+ /**
61
+ * Background slider hook result (if slider is enabled)
62
+ */
63
+ backgroundSlider?: UseHeroBackgroundSliderResult;
64
+
65
+ /**
66
+ * Whether background slider is enabled
67
+ */
68
+ hasBackgroundSlider: boolean;
58
69
  }
59
70
 
60
71
  /**
@@ -80,10 +91,25 @@ export function useHero(initialProps?: Partial<HeroProps>): UseHeroResult {
80
91
  ...initialProps,
81
92
  };
82
93
 
94
+ /**
95
+ * Check if background slider is enabled
96
+ */
97
+ const hasBackgroundSlider = !!defaultProps.backgroundSlider;
98
+
99
+ /**
100
+ * Initialize background slider hook if enabled
101
+ */
102
+ const backgroundSlider = hasBackgroundSlider && defaultProps.backgroundSlider
103
+ ? useHeroBackgroundSlider(defaultProps.backgroundSlider)
104
+ : undefined;
105
+
83
106
  /**
84
107
  * Check if the hero has a background image
108
+ * Slider takes precedence over single background image
85
109
  */
86
- const hasBackgroundImage = !!defaultProps.backgroundImageSrc;
110
+ const hasBackgroundImage = hasBackgroundSlider
111
+ ? true
112
+ : !!defaultProps.backgroundImageSrc || !!defaultProps.videoBackground;
87
113
 
88
114
  /**
89
115
  * Check if the hero has a foreground image
@@ -151,11 +177,12 @@ export function useHero(initialProps?: Partial<HeroProps>): UseHeroResult {
151
177
  }
152
178
  };
153
179
 
154
- // Apply parallax effect if enabled
180
+ // Apply parallax effect if enabled (disabled when slider is active)
155
181
  useEffect(() => {
156
182
  const heroElement = heroRef.current;
157
183
 
158
- if (heroElement && defaultProps.parallax && hasBackgroundImage) {
184
+ // Disable parallax when slider is active (conflicts with transitions)
185
+ if (heroElement && defaultProps.parallax && hasBackgroundImage && !hasBackgroundSlider) {
159
186
  applyParallaxEffect(heroElement, defaultProps.parallaxIntensity);
160
187
  }
161
188
 
@@ -164,7 +191,7 @@ export function useHero(initialProps?: Partial<HeroProps>): UseHeroResult {
164
191
  removeParallaxEffect(heroElement);
165
192
  }
166
193
  };
167
- }, [defaultProps.parallax, defaultProps.parallaxIntensity, hasBackgroundImage]);
194
+ }, [defaultProps.parallax, defaultProps.parallaxIntensity, hasBackgroundImage, hasBackgroundSlider]);
168
195
 
169
196
  /**
170
197
  * Generate hero class names based on props
@@ -246,5 +273,7 @@ export function useHero(initialProps?: Partial<HeroProps>): UseHeroResult {
246
273
  videoRef,
247
274
  applyParallaxEffect,
248
275
  removeParallaxEffect,
276
+ backgroundSlider,
277
+ hasBackgroundSlider,
249
278
  };
250
279
  }