@shohojdhara/atomix 0.2.1 → 0.2.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.
Files changed (201) hide show
  1. package/README.md +1 -28
  2. package/dist/atomix.css +1500 -241
  3. package/dist/atomix.min.css +6 -6
  4. package/dist/index.d.ts +1052 -194
  5. package/dist/index.esm.js +12201 -6066
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +5481 -2827
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.js +1 -1
  10. package/dist/index.min.js.map +1 -1
  11. package/dist/themes/boomdevs.css +1500 -301
  12. package/dist/themes/boomdevs.min.css +60 -8
  13. package/dist/themes/esrar.css +1500 -241
  14. package/dist/themes/esrar.min.css +6 -6
  15. package/dist/themes/mashroom.css +1496 -237
  16. package/dist/themes/mashroom.min.css +8 -8
  17. package/dist/themes/shaj-default.css +1451 -192
  18. package/dist/themes/shaj-default.min.css +6 -6
  19. package/package.json +66 -15
  20. package/src/components/Accordion/Accordion.stories.tsx +137 -0
  21. package/src/components/Accordion/Accordion.tsx +33 -3
  22. package/src/components/AtomixGlass/AtomixGlass.stories.tsx +3011 -0
  23. package/src/components/AtomixGlass/AtomixGlass.test.tsx +199 -0
  24. package/src/components/AtomixGlass/AtomixGlass.tsx +1281 -0
  25. package/src/components/AtomixGlass/AtomixGlassComprehensivePreview.stories.tsx +1369 -0
  26. package/src/components/AtomixGlass/README.md +134 -0
  27. package/src/components/AtomixGlass/index.ts +10 -0
  28. package/src/components/AtomixGlass/shader-utils.ts +140 -0
  29. package/src/components/AtomixGlass/utils.ts +8 -0
  30. package/src/components/Badge/Badge.stories.tsx +169 -0
  31. package/src/components/Badge/Badge.tsx +27 -2
  32. package/src/components/Button/Button.stories.tsx +345 -0
  33. package/src/components/Button/Button.tsx +35 -3
  34. package/src/components/Button/README.md +216 -0
  35. package/src/components/Callout/Callout.stories.tsx +813 -78
  36. package/src/components/Callout/Callout.test.tsx +368 -0
  37. package/src/components/Callout/Callout.tsx +26 -7
  38. package/src/components/Callout/README.md +409 -0
  39. package/src/components/Card/Card.stories.tsx +140 -0
  40. package/src/components/Card/Card.tsx +19 -3
  41. package/src/components/DatePicker/DatePicker copy.tsx +551 -0
  42. package/src/components/DatePicker/DatePicker.stories.tsx +188 -0
  43. package/src/components/DatePicker/DatePicker.tsx +379 -332
  44. package/src/components/DatePicker/readme.md +110 -1
  45. package/src/components/DatePicker/types.ts +8 -0
  46. package/src/components/Dropdown/Dropdown.stories.tsx +145 -0
  47. package/src/components/Dropdown/Dropdown.tsx +34 -5
  48. package/src/components/Footer/Footer.stories.tsx +388 -0
  49. package/src/components/Footer/Footer.tsx +197 -0
  50. package/src/components/Footer/FooterLink.tsx +72 -0
  51. package/src/components/Footer/FooterSection.tsx +87 -0
  52. package/src/components/Footer/FooterSocialLink.tsx +117 -0
  53. package/src/components/Footer/README.md +261 -0
  54. package/src/components/Footer/index.ts +13 -0
  55. package/src/components/Form/Checkbox.stories.tsx +101 -0
  56. package/src/components/Form/Checkbox.tsx +26 -2
  57. package/src/components/Form/Input.stories.tsx +124 -0
  58. package/src/components/Form/Input.tsx +36 -7
  59. package/src/components/Form/Radio.stories.tsx +139 -0
  60. package/src/components/Form/Radio.tsx +26 -2
  61. package/src/components/Form/Select.stories.tsx +110 -0
  62. package/src/components/Form/Select.tsx +26 -2
  63. package/src/components/Form/Textarea.stories.tsx +104 -0
  64. package/src/components/Form/Textarea.tsx +36 -7
  65. package/src/components/Hero/Hero.stories.tsx +54 -1
  66. package/src/components/Hero/Hero.tsx +70 -11
  67. package/src/components/Modal/Modal.stories.tsx +235 -0
  68. package/src/components/Modal/Modal.tsx +64 -35
  69. package/src/components/Pagination/Pagination.stories.tsx +101 -0
  70. package/src/components/Pagination/Pagination.tsx +25 -1
  71. package/src/components/Popover/Popover.stories.tsx +94 -0
  72. package/src/components/Popover/Popover.tsx +30 -4
  73. package/src/components/Rating/Rating.stories.tsx +112 -0
  74. package/src/components/Rating/Rating.tsx +25 -1
  75. package/src/components/SectionIntro/SectionIntro.tsx +9 -11
  76. package/src/components/Slider/Slider.stories.tsx +634 -50
  77. package/src/components/Slider/Slider.tsx +5 -3
  78. package/src/components/Steps/Steps.stories.tsx +119 -0
  79. package/src/components/Steps/Steps.tsx +32 -1
  80. package/src/components/Tab/Tab.stories.tsx +88 -0
  81. package/src/components/Tab/Tab.tsx +32 -1
  82. package/src/components/Toggle/Toggle.stories.tsx +92 -0
  83. package/src/components/Toggle/Toggle.tsx +32 -1
  84. package/src/components/Tooltip/Tooltip.stories.tsx +131 -0
  85. package/src/components/Tooltip/Tooltip.tsx +43 -7
  86. package/src/components/VideoPlayer/VideoPlayer.stories.tsx +1002 -196
  87. package/src/components/VideoPlayer/VideoPlayer.tsx +161 -4
  88. package/src/components/index.ts +14 -0
  89. package/src/layouts/Grid/Grid.stories.tsx +226 -159
  90. package/src/lib/composables/index.ts +4 -0
  91. package/src/lib/composables/useAtomixGlass.ts +71 -0
  92. package/src/lib/composables/useButton.ts +3 -1
  93. package/src/lib/composables/useCallout.ts +4 -1
  94. package/src/lib/composables/useFooter.ts +85 -0
  95. package/src/lib/composables/useGlassContainer.ts +168 -0
  96. package/src/lib/composables/useSlider.ts +191 -4
  97. package/src/lib/constants/components.ts +173 -0
  98. package/src/lib/types/components.ts +622 -0
  99. package/src/lib/utils/displacement-generator.ts +86 -0
  100. package/src/styles/01-settings/_index.scss +1 -0
  101. package/src/styles/01-settings/_settings.accordion.scss +20 -19
  102. package/src/styles/01-settings/_settings.animations.scss +5 -5
  103. package/src/styles/01-settings/_settings.avatar-group.scss +1 -1
  104. package/src/styles/01-settings/_settings.avatar.scss +17 -18
  105. package/src/styles/01-settings/_settings.background.scss +10 -0
  106. package/src/styles/01-settings/_settings.badge.scss +1 -1
  107. package/src/styles/01-settings/_settings.breadcrumb.scss +8 -2
  108. package/src/styles/01-settings/_settings.callout.scss +7 -7
  109. package/src/styles/01-settings/_settings.card.scss +2 -2
  110. package/src/styles/01-settings/_settings.chart.scss +7 -7
  111. package/src/styles/01-settings/_settings.checkbox-group.scss +5 -2
  112. package/src/styles/01-settings/_settings.checkbox.scss +10 -4
  113. package/src/styles/01-settings/_settings.countdown.scss +6 -4
  114. package/src/styles/01-settings/_settings.dropdown.scss +9 -7
  115. package/src/styles/01-settings/_settings.edge-panel.scss +3 -2
  116. package/src/styles/01-settings/_settings.footer.scss +125 -0
  117. package/src/styles/01-settings/_settings.form-group.scss +3 -1
  118. package/src/styles/01-settings/_settings.form.scss +4 -2
  119. package/src/styles/01-settings/_settings.hero.scss +9 -7
  120. package/src/styles/01-settings/_settings.input.scss +9 -7
  121. package/src/styles/01-settings/_settings.list-group.scss +4 -2
  122. package/src/styles/01-settings/_settings.list.scss +4 -2
  123. package/src/styles/01-settings/_settings.menu.scss +10 -8
  124. package/src/styles/01-settings/_settings.messages.scss +19 -17
  125. package/src/styles/01-settings/_settings.modal.scss +6 -4
  126. package/src/styles/01-settings/_settings.nav.scss +6 -4
  127. package/src/styles/01-settings/_settings.navbar.scss +8 -5
  128. package/src/styles/01-settings/_settings.pagination.scss +5 -3
  129. package/src/styles/01-settings/_settings.popover.scss +6 -4
  130. package/src/styles/01-settings/_settings.rating.scss +5 -3
  131. package/src/styles/01-settings/_settings.river.scss +8 -6
  132. package/src/styles/01-settings/_settings.sectionintro.scss +8 -6
  133. package/src/styles/01-settings/_settings.select.scss +7 -5
  134. package/src/styles/01-settings/_settings.side-menu.scss +15 -13
  135. package/src/styles/01-settings/_settings.spacing.scss +4 -0
  136. package/src/styles/01-settings/_settings.steps.scss +7 -5
  137. package/src/styles/01-settings/_settings.tabs.scss +7 -5
  138. package/src/styles/01-settings/_settings.testimonials.scss +6 -4
  139. package/src/styles/01-settings/_settings.toggle.scss +3 -1
  140. package/src/styles/01-settings/_settings.tooltip.scss +5 -3
  141. package/src/styles/01-settings/_settings.upload.scss +22 -20
  142. package/src/styles/02-tools/_tools.animations.scss +19 -0
  143. package/src/styles/02-tools/_tools.background.scss +87 -0
  144. package/src/styles/02-tools/_tools.glass.scss +1 -0
  145. package/src/styles/02-tools/_tools.rem.scss +18 -5
  146. package/src/styles/02-tools/_tools.utility-api.scss +32 -26
  147. package/src/styles/03-generic/_generic.root.scss +15 -2
  148. package/src/styles/04-elements/_elements.body.scss +6 -0
  149. package/src/styles/06-components/_components.accordion.scss +24 -4
  150. package/src/styles/06-components/_components.atomix-glass.scss +0 -0
  151. package/src/styles/06-components/_components.avatar-group.scss +2 -1
  152. package/src/styles/06-components/_components.avatar.scss +2 -1
  153. package/src/styles/06-components/_components.badge.scss +36 -1
  154. package/src/styles/06-components/_components.breadcrumb.scss +2 -1
  155. package/src/styles/06-components/_components.button.scss +14 -3
  156. package/src/styles/06-components/_components.callout.scss +44 -4
  157. package/src/styles/06-components/_components.card.scss +21 -2
  158. package/src/styles/06-components/_components.chart.scss +3 -2
  159. package/src/styles/06-components/_components.checkbox.scss +2 -1
  160. package/src/styles/06-components/_components.color-mode-toggle.scss +3 -2
  161. package/src/styles/06-components/_components.countdown.scss +2 -1
  162. package/src/styles/06-components/_components.data-table.scss +7 -6
  163. package/src/styles/06-components/_components.datepicker.scss +20 -1
  164. package/src/styles/06-components/_components.dropdown.scss +11 -4
  165. package/src/styles/06-components/_components.edge-panel.scss +4 -3
  166. package/src/styles/06-components/_components.footer.scss +825 -0
  167. package/src/styles/06-components/_components.form-group.scss +1 -0
  168. package/src/styles/06-components/_components.hero.scss +4 -4
  169. package/src/styles/06-components/_components.image-gallery.scss +1 -0
  170. package/src/styles/06-components/_components.input.scss +33 -2
  171. package/src/styles/06-components/_components.list-group.scss +3 -2
  172. package/src/styles/06-components/_components.list.scss +2 -1
  173. package/src/styles/06-components/_components.menu.scss +5 -4
  174. package/src/styles/06-components/_components.messages.scss +8 -7
  175. package/src/styles/06-components/_components.modal.scss +3 -2
  176. package/src/styles/06-components/_components.nav.scss +6 -5
  177. package/src/styles/06-components/_components.navbar.scss +4 -3
  178. package/src/styles/06-components/_components.pagination.scss +2 -1
  179. package/src/styles/06-components/_components.photoviewer.scss +4 -3
  180. package/src/styles/06-components/_components.popover.scss +3 -2
  181. package/src/styles/06-components/_components.product-review.scss +3 -2
  182. package/src/styles/06-components/_components.progress.scss +3 -2
  183. package/src/styles/06-components/_components.river.scss +3 -2
  184. package/src/styles/06-components/_components.sectionintro.scss +2 -1
  185. package/src/styles/06-components/_components.select.scss +5 -4
  186. package/src/styles/06-components/_components.side-menu.scss +8 -7
  187. package/src/styles/06-components/_components.skeleton.scss +3 -2
  188. package/src/styles/06-components/_components.slider.scss +7 -6
  189. package/src/styles/06-components/_components.spinner.scss +1 -0
  190. package/src/styles/06-components/_components.steps.scss +3 -2
  191. package/src/styles/06-components/_components.tabs.scss +4 -3
  192. package/src/styles/06-components/_components.testimonials.scss +2 -1
  193. package/src/styles/06-components/_components.todo.scss +3 -2
  194. package/src/styles/06-components/_components.toggle.scss +5 -4
  195. package/src/styles/06-components/_components.tooltip.scss +3 -2
  196. package/src/styles/06-components/_components.upload.scss +4 -3
  197. package/src/styles/06-components/_components.video-player.scss +50 -27
  198. package/src/styles/06-components/_index.scss +2 -0
  199. package/src/styles/99-utilities/_utilities.glass-fixes.scss +48 -0
  200. package/dist/themes/yabai.css +0 -13711
  201. package/dist/themes/yabai.min.css +0 -189
@@ -1,54 +1,80 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
1
+ /**
2
+ * VideoPlayer.stories.tsx
3
+ *
4
+ * Comprehensive Storybook stories for the VideoPlayer component, showcasing
5
+ * various configurations, use cases, and best practices. The stories demonstrate
6
+ * the component's versatility across different video types, layouts, and features.
7
+ *
8
+ * @package Atomix
9
+ * @component VideoPlayer
10
+ */
11
+
12
+ import { Meta, StoryObj } from '@storybook/react';
13
+ import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
14
+ import React from 'react';
2
15
  import { fn } from '@storybook/test';
3
16
  import { VideoPlayerProps } from '../../lib/types/components';
4
17
  import { VideoPlayer } from './VideoPlayer';
18
+ import type { RefObject } from 'react';
5
19
 
20
+ /**
21
+ * Storybook meta configuration for VideoPlayer component
22
+ *
23
+ * This defines the component's metadata, documentation, and controls
24
+ * for the Storybook interface.
25
+ */
6
26
  const meta: Meta<typeof VideoPlayer> = {
7
27
  title: 'Components/VideoPlayer',
8
28
  component: VideoPlayer,
9
29
  parameters: {
10
30
  layout: 'centered',
11
- backgrounds: {
12
- default: 'dark',
13
- },
14
31
  docs: {
15
32
  description: {
16
33
  component: `
17
34
  # VideoPlayer Component
18
35
 
19
- An advanced, modern video player with custom controls, keyboard shortcuts, picture-in-picture support, fullscreen capabilities, and comprehensive accessibility features. Now supports both regular video files and YouTube embeds.
20
-
21
- ## Features
36
+ An advanced, modern video player with comprehensive features, accessibility support, and optional glass morphism effects. Supports both regular video files and YouTube embeds with seamless integration.
22
37
 
23
- - **Dual Video Support**: Regular video files and YouTube embeds
24
- - **Custom Controls**: Play/pause, seek, volume, fullscreen, picture-in-picture (for regular videos)
25
- - **YouTube Integration**: Seamless YouTube video embedding with native controls
26
- - **Keyboard Shortcuts**: Space (play/pause), arrows (seek/volume), M (mute), F (fullscreen)
27
- - **Quality Selection**: Multiple video quality options
28
- - **Playback Speed**: Adjustable playback rates
29
- - **Subtitles Support**: Multiple subtitle tracks
30
- - **Responsive Design**: Works on all screen sizes
31
- - **Accessibility**: Full ARIA support and keyboard navigation
32
- - **Modern UI**: Sleek, customizable interface
38
+ ## Key Features
33
39
 
34
- ## YouTube Support
40
+ ### 🎥 **Dual Video Support**
41
+ - **Regular Videos**: Native HTML5 video with custom controls
42
+ - **YouTube Integration**: Seamless YouTube embedding with auto-detection
35
43
 
36
- - **Multiple Input Methods**: Use \`youtubeId\` prop, \`type="youtube"\`, or YouTube URLs in \`src\`
37
- - **Auto-Detection**: Automatically detects YouTube URLs and switches to embed mode
38
- - **Native Controls**: Uses YouTube's native player controls for optimal experience
39
- - **All YouTube Features**: Supports autoplay, muting, looping, and fullscreen
44
+ ### **Glass Morphism Effects**
45
+ - **Configurable Glass Overlay**: Optional frosted glass effects with AtomixGlass integration
46
+ - **Custom Content Support**: Interactive overlays and call-to-action elements
47
+ - **Multiple Glass Modes**: Standard, polar, prominent, and shader effects
40
48
 
41
- ## Keyboard Shortcuts (Regular Videos)
49
+ ### 🎛️ **Advanced Controls**
50
+ - **Custom UI**: Modern, responsive control interface
51
+ - **Quality Selection**: Multiple video resolution options
52
+ - **Playback Speed**: Adjustable speed controls (0.25x to 4x)
53
+ - **Subtitle Support**: Multi-language subtitle tracks with WebVTT
42
54
 
43
- - **Space**: Play/Pause
44
- - **Left/Right Arrow**: Seek backward/forward 10 seconds
45
- - **Up/Down Arrow**: Volume up/down
55
+ ### ⌨️ **Keyboard Shortcuts**
56
+ - **Space/K**: Play/Pause
57
+ - **Left/Right Arrows**: Seek ±10 seconds
58
+ - **Up/Down Arrows**: Volume control
46
59
  - **M**: Toggle mute
47
60
  - **F**: Toggle fullscreen
61
+
62
+ ### 🌟 **Premium Features**
63
+ - **Ambient Mode**: YouTube-style background glow effect
64
+ - **Picture-in-Picture**: Native PiP support for regular videos
65
+ - **Download & Share**: Built-in download and sharing capabilities
66
+ - **Responsive Design**: Adapts to any screen size
67
+ - **Accessibility**: Full ARIA support and screen reader compatibility
68
+
69
+ ### 📱 **Multi-Platform**
70
+ - **Cross-Browser**: Works on all modern browsers
71
+ - **Mobile Optimized**: Touch-friendly controls and responsive layout
72
+ - **Performance**: Optimized for smooth playback and effects
48
73
  `,
49
74
  },
50
75
  },
51
76
  },
77
+ tags: ['autodocs'],
52
78
  argTypes: {
53
79
  src: {
54
80
  control: 'text',
@@ -57,7 +83,7 @@ An advanced, modern video player with custom controls, keyboard shortcuts, pictu
57
83
  type: {
58
84
  control: 'select',
59
85
  options: ['video', 'youtube'],
60
- description: 'Video player type',
86
+ description: 'Video player type - automatically detected for YouTube URLs',
61
87
  },
62
88
  youtubeId: {
63
89
  control: 'text',
@@ -65,44 +91,77 @@ An advanced, modern video player with custom controls, keyboard shortcuts, pictu
65
91
  },
66
92
  poster: {
67
93
  control: 'text',
68
- description: 'Poster image URL',
94
+ description: 'Poster image URL for video thumbnail',
69
95
  },
70
96
  autoplay: {
71
97
  control: 'boolean',
72
- description: 'Whether video should autoplay',
98
+ description: 'Auto-start video playback (requires muted for most browsers)',
73
99
  },
74
100
  loop: {
75
101
  control: 'boolean',
76
- description: 'Whether video should loop',
102
+ description: 'Loop video playback infinitely',
77
103
  },
78
104
  muted: {
79
105
  control: 'boolean',
80
- description: 'Whether video should be muted',
106
+ description: 'Start video in muted state',
81
107
  },
82
108
  controls: {
83
109
  control: 'boolean',
84
- description: 'Whether to show custom controls',
110
+ description: 'Show custom video controls (not applicable to YouTube)',
111
+ },
112
+ preload: {
113
+ control: 'select',
114
+ options: ['none', 'metadata', 'auto'],
115
+ description: 'Video preload strategy',
116
+ },
117
+ width: {
118
+ control: 'text',
119
+ description: 'Player width (CSS value)',
120
+ },
121
+ height: {
122
+ control: 'text',
123
+ description: 'Player height (CSS value)',
85
124
  },
86
125
  aspectRatio: {
87
126
  control: 'select',
88
- options: ['16:9', '4:3', '21:9', '1:1'],
127
+ options: ['16:9', '4:3', '21:9', '1:1', '9:16'],
89
128
  description: 'Video aspect ratio',
90
129
  },
91
130
  showDownload: {
92
131
  control: 'boolean',
93
- description: 'Whether to show download button',
132
+ description: 'Show download button (regular videos only)',
94
133
  },
95
134
  showShare: {
96
135
  control: 'boolean',
97
- description: 'Whether to show share button',
136
+ description: 'Show share button',
98
137
  },
99
138
  showSettings: {
100
139
  control: 'boolean',
101
- description: 'Whether to show settings menu',
140
+ description: 'Show settings menu with quality, speed, and subtitle options',
141
+ },
142
+ playbackRates: {
143
+ control: 'object',
144
+ description: 'Available playback speed options',
102
145
  },
103
146
  ambientMode: {
104
147
  control: 'boolean',
105
- description: 'Enable ambient mode (YouTube-like background glow)',
148
+ description: 'Enable ambient mode with background glow effect',
149
+ },
150
+ glass: {
151
+ control: 'object',
152
+ description: 'Glass morphism configuration (boolean or AtomixGlass config object)',
153
+ },
154
+ glassOpacity: {
155
+ control: { type: 'range', min: 0, max: 1, step: 0.05 },
156
+ description: 'Glass overlay opacity (0-1)',
157
+ },
158
+ glassContent: {
159
+ control: 'text',
160
+ description: 'Custom React content to display over the glass layer',
161
+ },
162
+ className: {
163
+ control: 'text',
164
+ description: 'Additional CSS class names',
106
165
  },
107
166
  },
108
167
  };
@@ -110,25 +169,174 @@ An advanced, modern video player with custom controls, keyboard shortcuts, pictu
110
169
  export default meta;
111
170
  type Story = StoryObj<VideoPlayerProps>;
112
171
 
113
- // Sample video URLs (using Sintel - open source test video with subtitles)
114
- const sampleVideo = 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4';
115
- const samplePoster =
116
- 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/Sintel.jpg';
172
+ /**
173
+ * Background Wrapper Component
174
+ *
175
+ * Provides consistent background styling for video player stories
176
+ */
177
+ interface BackgroundWrapperProps {
178
+ children: React.ReactNode;
179
+ backgroundImage?: string;
180
+ backgroundIndex?: number;
181
+ overlay?: boolean;
182
+ overlayColor?: string;
183
+ overlayOpacity?: number;
184
+ height?: string;
185
+ width?: string;
186
+ borderRadius?: string;
187
+ padding?: string;
188
+ className?: string;
189
+ style?: React.CSSProperties;
190
+ interactive?: boolean;
191
+ }
192
+
193
+ const backgroundImages = [
194
+ // 0: Tech gradient - modern, professional
195
+ 'https://images.unsplash.com/photo-1636690636968-4568d7e94fe7?q=80&w=2670&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
196
+ // 1: Purple cosmic - entertainment focused
197
+ 'https://images.unsplash.com/photo-1534796636912-3b95b3ab5986?q=80&w=2071&auto=format&fit=crop',
198
+ // 2: Cinematic landscape - movie/video theme
199
+ 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2070&auto=format&fit=crop',
200
+ // 3: Abstract waves - fluid, dynamic
201
+ 'https://images.unsplash.com/photo-1614850715649-1d0106293bd1?q=80&w=2070&auto=format&fit=crop',
202
+ // 4: Gaming/streaming setup
203
+ 'https://images.unsplash.com/photo-1493711662062-fa541adb3fc8?q=80&w=2070&auto=format&fit=crop',
204
+ ];
205
+
206
+ const BackgroundWrapper = ({
207
+ children,
208
+ backgroundImage,
209
+ backgroundIndex,
210
+ overlay = false,
211
+ overlayColor = 'rgba(0,0,0,0)',
212
+ overlayOpacity = 1,
213
+ height = '90vh',
214
+ width = '90vw',
215
+ borderRadius = '12px',
216
+ padding = '24px',
217
+ className = '',
218
+ style = {},
219
+ }: BackgroundWrapperProps) => {
220
+ const bgImage =
221
+ backgroundIndex !== undefined ? backgroundImages[backgroundIndex] : backgroundImage;
222
+ const finalOverlayColor = overlay ? 'rgba(0,0,0,0.5)' : overlayColor;
223
+ const finalOverlayOpacity = overlay ? 0.5 : overlayOpacity;
224
+
225
+ return (
226
+ <div
227
+ className={`atomix-video-background ${className}`}
228
+ style={{
229
+ position: 'relative',
230
+ width: width,
231
+ minHeight: height,
232
+ height: '100%',
233
+ backgroundImage: bgImage ? `url(${bgImage})` : undefined,
234
+ backgroundColor: !bgImage ? '#0f0f23' : undefined,
235
+ backgroundSize: 'cover',
236
+ backgroundPosition: 'center',
237
+ backgroundAttachment: 'fixed',
238
+ display: 'flex',
239
+ alignItems: 'center',
240
+ justifyContent: 'center',
241
+ borderRadius: borderRadius,
242
+ padding: padding,
243
+ ...style,
244
+ }}
245
+ >
246
+ {finalOverlayOpacity > 0 && (
247
+ <div
248
+ style={{
249
+ position: 'absolute',
250
+ top: 0,
251
+ left: 0,
252
+ right: 0,
253
+ bottom: 0,
254
+ backgroundColor: finalOverlayColor,
255
+ opacity: finalOverlayOpacity,
256
+ zIndex: 1,
257
+ }}
258
+ />
259
+ )}
260
+ <div
261
+ style={{
262
+ position: 'relative',
263
+ width: '100%',
264
+ height: '100%',
265
+ display: 'flex',
266
+ alignItems: 'center',
267
+ justifyContent: 'center',
268
+ zIndex: 2,
269
+ }}
270
+ >
271
+ {children}
272
+ </div>
273
+ </div>
274
+ );
275
+ };
276
+
277
+ /**
278
+ * Sample video URLs and configurations
279
+ */
280
+ // Different video sources for various stories
281
+ const videoSources = {
282
+ sintel: {
283
+ src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4',
284
+ poster: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/Sintel.jpg',
285
+ },
286
+ bigBuckBunny: {
287
+ src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
288
+ poster:
289
+ 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg',
290
+ },
291
+ elephantsDream: {
292
+ src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4',
293
+ poster:
294
+ 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ElephantsDream.jpg',
295
+ },
296
+ forBiggerBlazes: {
297
+ src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4',
298
+ poster:
299
+ 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ForBiggerBlazes.jpg',
300
+ },
301
+ tearsOfSteel: {
302
+ src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/TearsOfSteel.mp4',
303
+ poster:
304
+ 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/TearsOfSteel.jpg',
305
+ },
306
+ subaru: {
307
+ src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/SubaruOutbackOnStreetAndDirt.mp4',
308
+ poster:
309
+ 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/SubaruOutbackOnStreetAndDirt.jpg',
310
+ },
311
+ volks: {
312
+ src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/VolkswagenGTIReview.mp4',
313
+ poster:
314
+ 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/VolkswagenGTIReview.jpg',
315
+ },
316
+ weAreGoingOnBullrun: {
317
+ src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/WeAreGoingOnBullrun.mp4',
318
+ poster:
319
+ 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/WeAreGoingOnBullrun.jpg',
320
+ },
321
+ };
322
+
323
+ const sampleVideo = videoSources.sintel.src;
324
+ const samplePoster = videoSources.sintel.poster;
117
325
 
118
326
  const sampleQualities = [
119
327
  {
120
- label: '1080p',
121
- src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4',
328
+ label: '1080p HD',
329
+ src: videoSources.sintel.src,
122
330
  resolution: '1920x1080',
123
331
  },
124
332
  {
125
333
  label: '720p',
126
- src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4',
334
+ src: videoSources.sintel.src,
127
335
  resolution: '1280x720',
128
336
  },
129
337
  {
130
338
  label: '480p',
131
- src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4',
339
+ src: videoSources.sintel.src,
132
340
  resolution: '854x480',
133
341
  },
134
342
  ];
@@ -141,8 +349,8 @@ const sampleSubtitles = [
141
349
  default: true,
142
350
  },
143
351
  {
144
- label: 'Spanish',
145
- src: 'data:text/vtt;charset=utf-8;base64,V0VCVlRUCgowMDowMDowMC4wMDAgLS0+IDAwOjAwOjA1LjAwMApTaW50ZWwgLSBVbiBjb3J0b21ldHJhamUgYW5pbWFkbyBkZSBjw7NkaWdvIGFiaWVydG8KCjAwOjAwOjA1LjAwMCAtLT4gMDA6MDA6MTAuMDAwClBvciBsYSBGdW5kYWNpw7NuIEJsZW5kZXIKCjAwOjAwOjEwLjAwMCAtLT4gMDA6MDA6MTUuMDAwCkVzdGEgZXMgdW5hIGRlbW9zdHJhY2nDs24gZGUgc3VidMOtdHVsb3MKCjAwOjAwOjE1LjAwMCAtLT4gMDA6MDA6MjAuMDAwClB1ZWRlcyBjYW1iaWFyIGVudHJlIGlkaW9tYXMKCjAwOjAwOjIwLjAwMCAtLT4gMDA6MDA6MjUuMDAwClVzYW5kbyBlbCBtZW7DuiBkZSBjb25maWd1cmFjacOzbg==',
352
+ label: 'Español',
353
+ src: 'data:text/vtt;charset=utf-8;base64,V0VCVlRUCgowMDowMDowMC4wMDAgLS0+IDAwOjAwOjA1LjAwMApTaW50ZWwgLSBVbiBjb3J0b21ldHJhamUgYW5pbWFkbyBkZSBjw7NkaWdvIGFiaWVydG8KCjAwOjAwOjA1LjAwMCAtLT4gMDA6MDA6MTAuMDAwClBvciBsYSBGdW5kYWNpw7NuIEJsZW5kZXIKCjAwOjAwOjEwLjAwMCAtLT4gMDA6MDA6MTUuMDAwCkVzdGEgZXMgdW5hIGRlbW9zdHJhY2nDs24gZGUgc3VidMOtdHVsb3MKCjAwOjAwOjE1LjAwMCAtLT4gMDA6MDA6MjAuMDAwClB1ZWRlcyBjYW1iaWFyIGVudHJlIGlkaW9tYXMKCjAwOjAwOjIwLjAwMCAtLT4gMDA:MDA6MjUuMDAwClVzYW5kbyBlbCBtZW7DuiBkZSBjb25maWd1cmFjacOzbg==',
146
354
  srcLang: 'es',
147
355
  },
148
356
  {
@@ -152,12 +360,21 @@ const sampleSubtitles = [
152
360
  },
153
361
  ];
154
362
 
363
+ /**
364
+ * Default VideoPlayer showcase
365
+ *
366
+ * Demonstrates the component with balanced settings suitable for most use cases.
367
+ * Features clean, modern controls and responsive design.
368
+ */
155
369
  export const Default: Story = {
156
370
  args: {
157
- src: sampleVideo,
158
- poster: samplePoster,
371
+ src: videoSources.sintel.src,
372
+ poster: videoSources.sintel.poster,
159
373
  width: '800px',
160
374
  height: '450px',
375
+ controls: true,
376
+ showSettings: true,
377
+ quality: sampleQualities,
161
378
  onPlay: fn(),
162
379
  onPause: fn(),
163
380
  onEnded: fn(),
@@ -166,55 +383,106 @@ export const Default: Story = {
166
383
  onFullscreenChange: fn(),
167
384
  onError: fn(),
168
385
  },
386
+ decorators: [
387
+ Story => (
388
+ <BackgroundWrapper
389
+ backgroundIndex={0}
390
+ height="70vh"
391
+ width="90vw"
392
+ overlayOpacity={0.1}
393
+ overlayColor="rgba(0,0,0,0.3)"
394
+ >
395
+ <Story />
396
+ </BackgroundWrapper>
397
+ ),
398
+ ],
399
+ parameters: {
400
+ docs: {
401
+ description: {
402
+ story:
403
+ 'The default VideoPlayer configuration with modern controls, quality selection, and responsive design. Perfect for most video playback scenarios with a clean, professional interface.',
404
+ },
405
+ },
406
+ },
169
407
  };
170
408
 
171
- export const WithAllFeatures: Story = {
409
+ /**
410
+ * YouTube Integration Examples
411
+ */
412
+ export const YouTubeEmbed: Story = {
172
413
  args: {
173
- src: sampleVideo,
174
- poster: samplePoster,
414
+ type: 'youtube',
415
+ youtubeId: 'eIho2S0ZahI',
175
416
  width: '800px',
176
417
  height: '450px',
177
- showDownload: true,
178
- showShare: true,
179
- showSettings: true,
180
- quality: sampleQualities,
181
- subtitles: sampleSubtitles,
182
- playbackRates: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2],
418
+ autoplay: false,
419
+ muted: false,
183
420
  onPlay: fn(),
184
421
  onPause: fn(),
185
422
  onEnded: fn(),
186
- onTimeUpdate: fn(),
187
- onVolumeChange: fn(),
188
- onFullscreenChange: fn(),
189
- onError: fn(),
423
+ },
424
+ decorators: [
425
+ Story => (
426
+ <BackgroundWrapper backgroundIndex={1} height="60vh" width="85vw" overlayOpacity={0.2}>
427
+ <Story />
428
+ </BackgroundWrapper>
429
+ ),
430
+ ],
431
+ parameters: {
432
+ docs: {
433
+ description: {
434
+ story:
435
+ "YouTube video integration using the youtubeId prop. Automatically uses YouTube's native player with all standard features including fullscreen, quality selection, and captions.",
436
+ },
437
+ },
190
438
  },
191
439
  };
192
440
 
193
- export const AutoplayMuted: Story = {
441
+ export const YouTubeURL: Story = {
194
442
  args: {
195
- src: sampleVideo,
196
- poster: samplePoster,
197
- autoplay: true,
198
- muted: true,
199
- width: '600px',
200
- height: '338px',
443
+ src: 'https://www.youtube.com/watch?v=eIho2S0ZahI',
444
+ width: '800px',
445
+ height: '450px',
446
+ autoplay: false,
447
+ muted: false,
201
448
  onPlay: fn(),
202
449
  onPause: fn(),
203
450
  onEnded: fn(),
204
- onTimeUpdate: fn(),
205
- onVolumeChange: fn(),
206
- onFullscreenChange: fn(),
207
- onError: fn(),
451
+ },
452
+ decorators: [
453
+ Story => (
454
+ <BackgroundWrapper backgroundIndex={1} height="60vh" width="85vw" overlayOpacity={0.2}>
455
+ <Story />
456
+ </BackgroundWrapper>
457
+ ),
458
+ ],
459
+ parameters: {
460
+ docs: {
461
+ description: {
462
+ story:
463
+ 'YouTube video using a standard YouTube URL in the src prop. The component automatically detects YouTube URLs and switches to embed mode for optimal experience.',
464
+ },
465
+ },
208
466
  },
209
467
  };
210
468
 
211
- export const NoControls: Story = {
469
+ /**
470
+ * Advanced Features Showcase
471
+ */
472
+ export const AdvancedFeatures: Story = {
212
473
  args: {
213
- src: sampleVideo,
214
- poster: samplePoster,
215
- controls: false,
216
- width: '600px',
217
- height: '338px',
474
+ src: videoSources.bigBuckBunny.src,
475
+ poster: videoSources.bigBuckBunny.poster,
476
+ width: '900px',
477
+ height: '506px',
478
+ controls: true,
479
+ showDownload: true,
480
+ showShare: true,
481
+ showSettings: true,
482
+ quality: sampleQualities,
483
+ subtitles: sampleSubtitles,
484
+ playbackRates: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3],
485
+ ambientMode: false,
218
486
  onPlay: fn(),
219
487
  onPause: fn(),
220
488
  onEnded: fn(),
@@ -223,14 +491,36 @@ export const NoControls: Story = {
223
491
  onFullscreenChange: fn(),
224
492
  onError: fn(),
225
493
  },
494
+ decorators: [
495
+ Story => (
496
+ <BackgroundWrapper backgroundIndex={0} height="75vh" width="95vw" overlayOpacity={0.15}>
497
+ <Story />
498
+ </BackgroundWrapper>
499
+ ),
500
+ ],
501
+ parameters: {
502
+ docs: {
503
+ description: {
504
+ story:
505
+ 'Complete showcase of all VideoPlayer features including quality selection, subtitles, playback speed controls, download/share buttons, and comprehensive settings menu. Demonstrates the full capability of the component.',
506
+ },
507
+ },
508
+ },
226
509
  };
227
510
 
228
- export const SquareAspectRatio: Story = {
511
+ /**
512
+ * Ambient Mode Example
513
+ */
514
+ export const AmbientMode: Story = {
229
515
  args: {
230
- src: sampleVideo,
516
+ src: videoSources.elephantsDream.src,
231
517
  poster: samplePoster,
232
- aspectRatio: '1:1',
233
- width: '400px',
518
+ width: '800px',
519
+ height: '450px',
520
+ ambientMode: true,
521
+ autoplay: true,
522
+ muted: true,
523
+ controls: true,
234
524
  onPlay: fn(),
235
525
  onPause: fn(),
236
526
  onEnded: fn(),
@@ -239,14 +529,46 @@ export const SquareAspectRatio: Story = {
239
529
  onFullscreenChange: fn(),
240
530
  onError: fn(),
241
531
  },
532
+ decorators: [
533
+ Story => (
534
+ <BackgroundWrapper
535
+ backgroundIndex={2}
536
+ height="80vh"
537
+ width="95vw"
538
+ overlayOpacity={0.6}
539
+ overlayColor="rgba(0,0,0,0.7)"
540
+ padding="60px"
541
+ >
542
+ <Story />
543
+ </BackgroundWrapper>
544
+ ),
545
+ ],
546
+ parameters: {
547
+ docs: {
548
+ description: {
549
+ story:
550
+ 'Ambient mode creates a YouTube-style background glow effect that extends the video colors beyond the player boundaries, creating an immersive viewing experience perfect for entertainment content.',
551
+ },
552
+ },
553
+ },
242
554
  };
243
555
 
244
- export const UltraWideAspectRatio: Story = {
556
+ /**
557
+ * Glass Morphism Variants
558
+ */
559
+ export const GlassEffect: Story = {
245
560
  args: {
246
- src: sampleVideo,
247
- poster: samplePoster,
248
- aspectRatio: '21:9',
561
+ src: videoSources.forBiggerBlazes.src,
562
+ poster: videoSources.forBiggerBlazes.poster,
249
563
  width: '800px',
564
+ height: '450px',
565
+ glass: true,
566
+ glassOpacity: 0.4,
567
+ controls: true,
568
+ showDownload: true,
569
+ showShare: true,
570
+ showSettings: true,
571
+ quality: sampleQualities,
250
572
  onPlay: fn(),
251
573
  onPause: fn(),
252
574
  onEnded: fn(),
@@ -255,17 +577,46 @@ export const UltraWideAspectRatio: Story = {
255
577
  onFullscreenChange: fn(),
256
578
  onError: fn(),
257
579
  },
580
+ decorators: [
581
+ Story => (
582
+ <BackgroundWrapper backgroundIndex={3} height="70vh" width="90vw" overlayOpacity={0.1}>
583
+ <Story />
584
+ </BackgroundWrapper>
585
+ ),
586
+ ],
587
+ parameters: {
588
+ docs: {
589
+ description: {
590
+ story:
591
+ 'VideoPlayer with glass morphism effects overlay. The translucent glass layer adds visual depth and modern aesthetics while maintaining full functionality of video controls.',
592
+ },
593
+ },
594
+ },
258
595
  };
259
596
 
260
- export const ResponsivePlayer: Story = {
597
+ export const GlassCustom: Story = {
261
598
  args: {
262
- src: sampleVideo,
263
- poster: samplePoster,
264
- width: '100%',
265
- aspectRatio: '16:9',
599
+ src: videoSources.tearsOfSteel.src,
600
+ poster: videoSources.tearsOfSteel.poster,
601
+ width: '800px',
602
+ height: '450px',
603
+ glass: {
604
+ displacementScale: 35,
605
+ blurAmount: 0.25,
606
+ saturation: 180,
607
+ aberrationIntensity: 2.5,
608
+ elasticity: 0.4,
609
+ cornerRadius: 20,
610
+ mode: 'prominent',
611
+ overLight: false,
612
+ },
613
+ glassOpacity: 0.5,
614
+ controls: true,
266
615
  showDownload: true,
267
616
  showShare: true,
617
+ showSettings: true,
268
618
  quality: sampleQualities,
619
+ subtitles: sampleSubtitles,
269
620
  onPlay: fn(),
270
621
  onPause: fn(),
271
622
  onEnded: fn(),
@@ -276,21 +627,178 @@ export const ResponsivePlayer: Story = {
276
627
  },
277
628
  decorators: [
278
629
  Story => (
279
- <div style={{ width: '100%', maxWidth: '800px', margin: '0 auto' }}>
630
+ <BackgroundWrapper
631
+ style={{
632
+ background: 'radial-gradient(circle at 50% 50%, #ff6b6b 0%, #4ecdc4 50%, #45b7d1 100%)',
633
+ }}
634
+ height="75vh"
635
+ width="90vw"
636
+ padding="60px"
637
+ >
280
638
  <Story />
281
- </div>
639
+ </BackgroundWrapper>
282
640
  ),
283
641
  ],
642
+ parameters: {
643
+ docs: {
644
+ description: {
645
+ story:
646
+ 'Advanced glass morphism configuration with custom displacement, blur, and saturation settings. Demonstrates the full customization potential of the glass effect overlay.',
647
+ },
648
+ },
649
+ },
284
650
  };
285
651
 
286
- export const WithCustomPlaybackRates: Story = {
652
+ export const GlassWithInteractiveContent: Story = {
653
+ render: args => {
654
+ // eslint-disable-next-line react-hooks/rules-of-hooks
655
+ const [showOverlay, setShowOverlay] = useState(true);
656
+
657
+ return (
658
+ <BackgroundWrapper
659
+ style={{
660
+ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%)',
661
+ }}
662
+ height="80vh"
663
+ width="90vw"
664
+ padding="60px"
665
+ >
666
+ <VideoPlayer
667
+ {...args}
668
+ glassContent={
669
+ showOverlay ? (
670
+ <div
671
+ style={{
672
+ background: 'rgba(255, 255, 255, 0.15)',
673
+ backdropFilter: 'blur(20px)',
674
+ borderRadius: '20px',
675
+ padding: '40px',
676
+ textAlign: 'center',
677
+ border: '1px solid rgba(255, 255, 255, 0.3)',
678
+ maxWidth: '500px',
679
+ boxShadow: '0 12px 40px rgba(0, 0, 0, 0.3)',
680
+ }}
681
+ >
682
+ <h2
683
+ style={{
684
+ margin: '0 0 20px 0',
685
+ color: 'white',
686
+ fontSize: '28px',
687
+ fontWeight: '600',
688
+ textShadow: '0 2px 8px rgba(0, 0, 0, 0.5)',
689
+ }}
690
+ >
691
+ 🎬 Premium Cinema Experience
692
+ </h2>
693
+ <p
694
+ style={{
695
+ margin: '0 0 30px 0',
696
+ color: 'rgba(255, 255, 255, 0.9)',
697
+ fontSize: '18px',
698
+ lineHeight: '1.6',
699
+ textShadow: '0 1px 4px rgba(0, 0, 0, 0.5)',
700
+ }}
701
+ >
702
+ Immerse yourself in a cinematic journey with our advanced glass morphism effects,
703
+ premium video quality, and interactive features designed for the ultimate viewing
704
+ experience.
705
+ </p>
706
+ <div
707
+ style={{
708
+ display: 'flex',
709
+ gap: '16px',
710
+ justifyContent: 'center',
711
+ flexWrap: 'wrap',
712
+ }}
713
+ >
714
+ <button
715
+ onClick={() => setShowOverlay(false)}
716
+ style={{
717
+ background:
718
+ 'linear-gradient(135deg, rgba(255, 255, 255, 0.25), rgba(255, 255, 255, 0.15))',
719
+ border: '1px solid rgba(255, 255, 255, 0.4)',
720
+ borderRadius: '14px',
721
+ color: 'white',
722
+ padding: '14px 28px',
723
+ cursor: 'pointer',
724
+ fontSize: '16px',
725
+ fontWeight: '600',
726
+ transition: 'all 0.3s ease',
727
+ textShadow: '0 1px 2px rgba(0, 0, 0, 0.5)',
728
+ boxShadow: '0 6px 20px rgba(0, 0, 0, 0.2)',
729
+ transform: 'translateY(0)',
730
+ }}
731
+ onMouseOver={e => {
732
+ const target = e.target as HTMLButtonElement;
733
+ target.style.background =
734
+ 'linear-gradient(135deg, rgba(255, 255, 255, 0.35), rgba(255, 255, 255, 0.25))';
735
+ target.style.transform = 'translateY(-2px)';
736
+ target.style.boxShadow = '0 8px 25px rgba(0, 0, 0, 0.3)';
737
+ }}
738
+ onMouseOut={e => {
739
+ const target = e.target as HTMLButtonElement;
740
+ target.style.background =
741
+ 'linear-gradient(135deg, rgba(255, 255, 255, 0.25), rgba(255, 255, 255, 0.15))';
742
+ target.style.transform = 'translateY(0)';
743
+ target.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.2)';
744
+ }}
745
+ >
746
+ ▶ Start Watching
747
+ </button>
748
+ <button
749
+ style={{
750
+ background: 'rgba(255, 255, 255, 0.1)',
751
+ border: '1px solid rgba(255, 255, 255, 0.3)',
752
+ borderRadius: '14px',
753
+ color: 'white',
754
+ padding: '14px 28px',
755
+ cursor: 'pointer',
756
+ fontSize: '16px',
757
+ fontWeight: '500',
758
+ transition: 'all 0.3s ease',
759
+ textShadow: '0 1px 2px rgba(0, 0, 0, 0.5)',
760
+ }}
761
+ onMouseOver={e => {
762
+ const target = e.target as HTMLButtonElement;
763
+ target.style.background = 'rgba(255, 255, 255, 0.2)';
764
+ target.style.transform = 'translateY(-1px)';
765
+ }}
766
+ onMouseOut={e => {
767
+ const target = e.target as HTMLButtonElement;
768
+ target.style.background = 'rgba(255, 255, 255, 0.1)';
769
+ target.style.transform = 'translateY(0)';
770
+ }}
771
+ >
772
+ Learn More
773
+ </button>
774
+ </div>
775
+ </div>
776
+ ) : null
777
+ }
778
+ />
779
+ </BackgroundWrapper>
780
+ );
781
+ },
287
782
  args: {
288
783
  src: sampleVideo,
289
784
  poster: samplePoster,
290
- width: '700px',
291
- height: '394px',
292
- playbackRates: [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 3, 4],
785
+ width: '800px',
786
+ height: '450px',
787
+ glass: {
788
+ displacementScale: 30,
789
+ blurAmount: 0.2,
790
+ saturation: 170,
791
+ aberrationIntensity: 2,
792
+ elasticity: 0.3,
793
+ cornerRadius: 15,
794
+ mode: 'standard',
795
+ },
796
+ glassOpacity: 0.6,
797
+ controls: true,
798
+ showDownload: true,
799
+ showShare: true,
293
800
  showSettings: true,
801
+ quality: sampleQualities,
294
802
  onPlay: fn(),
295
803
  onPause: fn(),
296
804
  onEnded: fn(),
@@ -299,17 +807,30 @@ export const WithCustomPlaybackRates: Story = {
299
807
  onFullscreenChange: fn(),
300
808
  onError: fn(),
301
809
  },
810
+ parameters: {
811
+ docs: {
812
+ description: {
813
+ story:
814
+ 'Interactive content overlay demonstration with call-to-action elements. Shows how to create engaging pre-roll content that can be dismissed to reveal the video player underneath.',
815
+ },
816
+ },
817
+ },
302
818
  };
303
819
 
304
- export const MinimalPlayer: Story = {
820
+ /**
821
+ * Responsive and Layout Examples
822
+ */
823
+ export const ResponsivePlayer: Story = {
305
824
  args: {
306
- src: sampleVideo,
307
- poster: samplePoster,
308
- width: '400px',
309
- height: '225px',
310
- showDownload: false,
311
- showShare: false,
312
- showSettings: false,
825
+ src: videoSources.volks.src,
826
+ poster: videoSources.volks.poster,
827
+ width: '100%',
828
+ aspectRatio: '16:9',
829
+ controls: true,
830
+ showDownload: true,
831
+ showShare: true,
832
+ showSettings: true,
833
+ quality: sampleQualities,
313
834
  onPlay: fn(),
314
835
  onPause: fn(),
315
836
  onEnded: fn(),
@@ -318,17 +839,53 @@ export const MinimalPlayer: Story = {
318
839
  onFullscreenChange: fn(),
319
840
  onError: fn(),
320
841
  },
842
+ decorators: [
843
+ Story => (
844
+ <div
845
+ style={{
846
+ width: '100%',
847
+ maxWidth: '1200px',
848
+ margin: '0 auto',
849
+ padding: '20px',
850
+ background: 'linear-gradient(135deg, #1e3c72 0%, #2a5298 100%)',
851
+ borderRadius: '16px',
852
+ }}
853
+ >
854
+ <div
855
+ style={{
856
+ marginBottom: '20px',
857
+ textAlign: 'center',
858
+ color: 'white',
859
+ }}
860
+ >
861
+ <h3 style={{ margin: '0 0 10px 0', fontSize: '24px', fontWeight: '600' }}>
862
+ Responsive Video Player
863
+ </h3>
864
+ <p style={{ margin: 0, fontSize: '16px', opacity: 0.9 }}>
865
+ Adapts to any screen size with fluid width and maintained aspect ratio
866
+ </p>
867
+ </div>
868
+ <Story />
869
+ </div>
870
+ ),
871
+ ],
872
+ parameters: {
873
+ docs: {
874
+ description: {
875
+ story:
876
+ 'Fully responsive video player that adapts to container width while maintaining aspect ratio. Perfect for content management systems and responsive layouts.',
877
+ },
878
+ },
879
+ },
321
880
  };
322
881
 
323
- export const LoopingVideo: Story = {
882
+ export const SquareFormat: Story = {
324
883
  args: {
325
- src: sampleVideo,
326
- poster: samplePoster,
327
- loop: true,
328
- autoplay: true,
329
- muted: true,
884
+ src: videoSources.weAreGoingOnBullrun.src,
885
+ poster: videoSources.weAreGoingOnBullrun.poster,
886
+ aspectRatio: '1:1',
330
887
  width: '500px',
331
- height: '281px',
888
+ controls: true,
332
889
  onPlay: fn(),
333
890
  onPause: fn(),
334
891
  onEnded: fn(),
@@ -337,34 +894,39 @@ export const LoopingVideo: Story = {
337
894
  onFullscreenChange: fn(),
338
895
  onError: fn(),
339
896
  },
340
- };
341
-
342
- // Interactive story with event handlers
343
- export const WithEventHandlers: Story = {
344
- args: {
345
- src: sampleVideo,
346
- poster: samplePoster,
347
- width: '700px',
348
- height: '394px',
349
- onPlay: fn(),
350
- onPause: fn(),
351
- onEnded: fn(),
352
- onTimeUpdate: fn(),
353
- onVolumeChange: fn(),
354
- onFullscreenChange: fn(),
355
- onError: fn(),
897
+ decorators: [
898
+ Story => (
899
+ <BackgroundWrapper backgroundIndex={4} height="60vh" width="80vw" overlayOpacity={0.3}>
900
+ <div style={{ textAlign: 'center', color: 'white' }}>
901
+ <h3 style={{ margin: '0 0 20px 0', fontSize: '22px', fontWeight: '600' }}>
902
+ Square Format Video
903
+ </h3>
904
+ <p style={{ margin: '0 0 30px 0', fontSize: '16px', opacity: 0.9 }}>
905
+ Perfect for social media content and mobile-first designs
906
+ </p>
907
+ <Story />
908
+ </div>
909
+ </BackgroundWrapper>
910
+ ),
911
+ ],
912
+ parameters: {
913
+ docs: {
914
+ description: {
915
+ story:
916
+ 'Square aspect ratio (1:1) configuration ideal for social media content, Instagram-style videos, and mobile-optimized layouts.',
917
+ },
918
+ },
356
919
  },
357
920
  };
358
921
 
359
- export const AmbientMode: Story = {
922
+ export const VerticalFormat: Story = {
360
923
  args: {
361
- src: sampleVideo,
362
- poster: samplePoster,
363
- width: '800px',
364
- height: '450px',
365
- ambientMode: true,
366
- autoplay: true,
367
- muted: true,
924
+ src: videoSources.bigBuckBunny.src,
925
+ poster: videoSources.bigBuckBunny.poster,
926
+ aspectRatio: '9:16',
927
+ width: '360px',
928
+ controls: true,
929
+ showSettings: true,
368
930
  onPlay: fn(),
369
931
  onPause: fn(),
370
932
  onEnded: fn(),
@@ -373,45 +935,44 @@ export const AmbientMode: Story = {
373
935
  onFullscreenChange: fn(),
374
936
  onError: fn(),
375
937
  },
376
- parameters: {
377
- backgrounds: {
378
- default: 'dark',
379
- },
380
- },
381
938
  decorators: [
382
939
  Story => (
383
- <div style={{ padding: '2rem' }}>
384
- <Story />
385
- </div>
940
+ <BackgroundWrapper backgroundIndex={1} height="90vh" width="70vw" overlayOpacity={0.2}>
941
+ <div style={{ textAlign: 'center', color: 'white' }}>
942
+ <h3 style={{ margin: '0 0 20px 0', fontSize: '22px', fontWeight: '600' }}>
943
+ Vertical/Portrait Format
944
+ </h3>
945
+ <p style={{ margin: '0 0 30px 0', fontSize: '16px', opacity: 0.9 }}>
946
+ Optimized for mobile viewing and story-style content
947
+ </p>
948
+ <Story />
949
+ </div>
950
+ </BackgroundWrapper>
386
951
  ),
387
952
  ],
388
- };
389
-
390
- export const YouTubeEmbed: Story = {
391
- args: {
392
- type: 'youtube',
393
- youtubeId: 'dQw4w9WgXcQ',
394
- width: '800px',
395
- height: '450px',
396
- autoplay: false,
397
- muted: false,
398
- onPlay: fn(),
399
- onPause: fn(),
400
- onEnded: fn(),
401
- onTimeUpdate: fn(),
402
- onVolumeChange: fn(),
403
- onFullscreenChange: fn(),
404
- onError: fn(),
953
+ parameters: {
954
+ docs: {
955
+ description: {
956
+ story:
957
+ 'Vertical/portrait format (9:16) perfect for mobile-first content, TikTok-style videos, and story formats. Optimized for portrait viewing experiences.',
958
+ },
959
+ },
405
960
  },
406
961
  };
407
962
 
408
- export const YouTubeURL: Story = {
963
+ /**
964
+ * Specialized Configurations
965
+ */
966
+ export const MinimalPlayer: Story = {
409
967
  args: {
410
- src: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
411
- width: '800px',
412
- height: '450px',
413
- autoplay: false,
414
- muted: false,
968
+ src: videoSources.elephantsDream.src,
969
+ poster: videoSources.elephantsDream.poster,
970
+ width: '600px',
971
+ height: '338px',
972
+ controls: true,
973
+ showDownload: false,
974
+ showShare: false,
975
+ showSettings: false,
415
976
  onPlay: fn(),
416
977
  onPause: fn(),
417
978
  onEnded: fn(),
@@ -420,16 +981,41 @@ export const YouTubeURL: Story = {
420
981
  onFullscreenChange: fn(),
421
982
  onError: fn(),
422
983
  },
984
+ decorators: [
985
+ Story => (
986
+ <BackgroundWrapper backgroundIndex={0} height="60vh" width="80vw" overlayOpacity={0.1}>
987
+ <div style={{ textAlign: 'center', color: 'white' }}>
988
+ <h3 style={{ margin: '0 0 20px 0', fontSize: '22px', fontWeight: '600' }}>
989
+ Minimal Configuration
990
+ </h3>
991
+ <p style={{ margin: '0 0 30px 0', fontSize: '16px', opacity: 0.9 }}>
992
+ Clean, distraction-free video playback with essential controls only
993
+ </p>
994
+ <Story />
995
+ </div>
996
+ </BackgroundWrapper>
997
+ ),
998
+ ],
999
+ parameters: {
1000
+ docs: {
1001
+ description: {
1002
+ story:
1003
+ 'Minimal video player configuration with only essential playback controls. Perfect for situations where simplicity and focus on content are priorities.',
1004
+ },
1005
+ },
1006
+ },
423
1007
  };
424
1008
 
425
- export const YouTubeAutoplay: Story = {
1009
+ export const AutoplayMuted: Story = {
426
1010
  args: {
427
- type: 'youtube',
428
- youtubeId: 'dQw4w9WgXcQ',
429
- width: '800px',
430
- height: '450px',
1011
+ src: videoSources.forBiggerBlazes.src,
1012
+ poster: videoSources.forBiggerBlazes.poster,
431
1013
  autoplay: true,
432
1014
  muted: true,
1015
+ loop: true,
1016
+ width: '700px',
1017
+ height: '394px',
1018
+ controls: true,
433
1019
  onPlay: fn(),
434
1020
  onPause: fn(),
435
1021
  onEnded: fn(),
@@ -438,15 +1024,42 @@ export const YouTubeAutoplay: Story = {
438
1024
  onFullscreenChange: fn(),
439
1025
  onError: fn(),
440
1026
  },
1027
+ decorators: [
1028
+ Story => (
1029
+ <BackgroundWrapper backgroundIndex={2} height="60vh" width="85vw" overlayOpacity={0.2}>
1030
+ <div style={{ textAlign: 'center', color: 'white' }}>
1031
+ <h3 style={{ margin: '0 0 20px 0', fontSize: '22px', fontWeight: '600' }}>
1032
+ Autoplay & Loop Configuration
1033
+ </h3>
1034
+ <p style={{ margin: '0 0 30px 0', fontSize: '16px', opacity: 0.9 }}>
1035
+ Perfect for background videos and promotional content
1036
+ </p>
1037
+ <Story />
1038
+ </div>
1039
+ </BackgroundWrapper>
1040
+ ),
1041
+ ],
1042
+ parameters: {
1043
+ docs: {
1044
+ description: {
1045
+ story:
1046
+ 'Autoplay configuration with muted audio and loop enabled. Ideal for background videos, hero sections, and promotional content that needs to play automatically.',
1047
+ },
1048
+ },
1049
+ },
441
1050
  };
442
1051
 
1052
+ /**
1053
+ * Accessibility and Internationalization
1054
+ */
443
1055
  export const WithSubtitles: Story = {
444
1056
  args: {
445
- src: sampleVideo,
446
- poster: samplePoster,
1057
+ src: videoSources.tearsOfSteel.src,
1058
+ poster: videoSources.tearsOfSteel.poster,
447
1059
  width: '800px',
448
1060
  height: '450px',
449
1061
  subtitles: sampleSubtitles,
1062
+ controls: true,
450
1063
  showSettings: true,
451
1064
  onPlay: fn(),
452
1065
  onPause: fn(),
@@ -456,29 +1069,222 @@ export const WithSubtitles: Story = {
456
1069
  onFullscreenChange: fn(),
457
1070
  onError: fn(),
458
1071
  },
1072
+ decorators: [
1073
+ Story => (
1074
+ <BackgroundWrapper backgroundIndex={3} height="70vh" width="90vw" overlayOpacity={0.15}>
1075
+ <div style={{ textAlign: 'center', color: 'white', marginBottom: '30px' }}>
1076
+ <h3 style={{ margin: '0 0 10px 0', fontSize: '22px', fontWeight: '600' }}>
1077
+ Multi-Language Subtitles
1078
+ </h3>
1079
+ <p style={{ margin: 0, fontSize: '16px', opacity: 0.9 }}>
1080
+ Accessibility support with English, Spanish, and Bengali subtitle options
1081
+ </p>
1082
+ </div>
1083
+ <Story />
1084
+ </BackgroundWrapper>
1085
+ ),
1086
+ ],
1087
+ parameters: {
1088
+ docs: {
1089
+ description: {
1090
+ story:
1091
+ 'Multi-language subtitle support demonstration with WebVTT files. Users can switch between English, Spanish, and Bengali subtitles using the settings menu, enhancing accessibility and international reach.',
1092
+ },
1093
+ },
1094
+ },
459
1095
  };
460
1096
 
461
- export const WithBengaliSubtitles: Story = {
462
- args: {
463
- src: sampleVideo,
464
- poster: samplePoster,
465
- width: '800px',
466
- height: '450px',
467
- subtitles: [
468
- {
469
- label: 'বাংলা',
470
- src: 'data:text/vtt;charset=utf-8;base64,V0VCVlRUCgowMDowMDowMC4wMDAgLS0+IDAwOjAwOjA1LjAwMApzaW50ZWwgLSDgpI/gppXgpp/gpr8g4KST4KSq4KWH4KSoIOCmuOCni+CmsOCnjeCmuCDgpI/gp43gpq/gpr/gpq7gp4fgpp/gp4fgpqEg4KaV4KaX4Ka/4KaoCgowMDowMDowNS4wMDAgLS0+IDAwOjAwOjEwLjAwMApgpqzgp43gpqzgp4fgpqjgp43gpqHgpr7gprAg4Kar4Ka+4KaJ4KaP4KaH4Ka24KaoIOCmr+CmvuCmsOCmvwowMDowMDoxMC4wMDAgLS0+IDAwOjAwOjE1LjAwMApgpqHgpr/gpp/gpr8g4Ka44Ka+4KaW4KaX4Ka/4KaX4KaC4KaXIOCmj+CmsOCmvuCmqOCmvuCmrOCmvuCmsCDgpqjgpr/gpqbgprDgp43gprbgpqgKCjAwOjAwOjE1LjAwMCAtLT4gMDA6MDA6MjAuMDAwCuCmhuCmquCmqOCmvuCmsOCmviDgpq3gpr7gprfgpr7gprAg4Kau4Kav4KaX4KWHIOCmquCmsOCmv+CmrOCmsOCnjeCmpOCmqCDgppXgprDgpqTgp4cg4Kaq4Ka+4Kaw4KasCgowMDowMDoyMC4wMDAgLS0+IDAwOjAwOjI1LjAwMApgprjgp4fgpp/gpr/gppngprgg4Kau4KeH4Kao4KeB4KaXIOCmrOCnjeCmr+CmreCmvuCmsOCmviDgppXgprDgp4fgpqQ=',
471
- srcLang: 'bn',
472
- default: true,
1097
+ /**
1098
+ * Interactive Playground with Dynamic Controls
1099
+ */
1100
+ export const InteractivePlayground: Story = {
1101
+ render: () => {
1102
+ // eslint-disable-next-line react-hooks/rules-of-hooks
1103
+ const [settings, setSettings] = useState({
1104
+ aspectRatio: '16:9' as const,
1105
+ autoplay: false,
1106
+ muted: false,
1107
+ loop: false,
1108
+ controls: true,
1109
+ showDownload: true,
1110
+ showShare: true,
1111
+ showSettings: true,
1112
+ ambientMode: false,
1113
+ glass: false,
1114
+ glassOpacity: 0.4,
1115
+ backgroundIndex: 0,
1116
+ });
1117
+
1118
+ const handleChange = (property: string, value: any) => {
1119
+ setSettings(prev => ({
1120
+ ...prev,
1121
+ [property]: value,
1122
+ }));
1123
+ };
1124
+
1125
+ const aspectRatios = ['16:9', '4:3', '21:9', '1:1', '9:16'] as const;
1126
+
1127
+ return (
1128
+ <BackgroundWrapper
1129
+ backgroundIndex={settings.backgroundIndex}
1130
+ height="90vh"
1131
+ width="95vw"
1132
+ style={{ position: 'relative' }}
1133
+ >
1134
+ {/* Control Panel */}
1135
+ <div
1136
+ style={{
1137
+ position: 'absolute',
1138
+ top: '20px',
1139
+ left: '20px',
1140
+ width: '300px',
1141
+ padding: '20px',
1142
+ borderRadius: '12px',
1143
+ background: 'rgba(0,0,0,0.8)',
1144
+ backdropFilter: 'blur(20px)',
1145
+ border: '1px solid rgba(255,255,255,0.2)',
1146
+ color: 'white',
1147
+ fontSize: '14px',
1148
+ zIndex: 10,
1149
+ }}
1150
+ >
1151
+ <h3 style={{ margin: '0 0 20px 0', fontSize: '18px', textAlign: 'center' }}>
1152
+ VideoPlayer Controls
1153
+ </h3>
1154
+
1155
+ {/* Aspect Ratio */}
1156
+ <div style={{ marginBottom: '16px' }}>
1157
+ <label style={{ display: 'block', marginBottom: '6px', fontWeight: '500' }}>
1158
+ Aspect Ratio
1159
+ </label>
1160
+ <select
1161
+ value={settings.aspectRatio}
1162
+ onChange={e => handleChange('aspectRatio', e.target.value)}
1163
+ style={{
1164
+ width: '100%',
1165
+ padding: '8px',
1166
+ backgroundColor: 'rgba(255,255,255,0.1)',
1167
+ color: 'white',
1168
+ border: '1px solid rgba(255,255,255,0.2)',
1169
+ borderRadius: '4px',
1170
+ }}
1171
+ >
1172
+ {aspectRatios.map(ratio => (
1173
+ <option key={ratio} value={ratio} style={{ backgroundColor: '#333' }}>
1174
+ {ratio}
1175
+ </option>
1176
+ ))}
1177
+ </select>
1178
+ </div>
1179
+
1180
+ {/* Background */}
1181
+ <div style={{ marginBottom: '16px' }}>
1182
+ <label style={{ display: 'block', marginBottom: '6px', fontWeight: '500' }}>
1183
+ Background ({settings.backgroundIndex + 1}/5)
1184
+ </label>
1185
+ <input
1186
+ type="range"
1187
+ min="0"
1188
+ max="4"
1189
+ value={settings.backgroundIndex}
1190
+ onChange={e => handleChange('backgroundIndex', parseInt(e.target.value))}
1191
+ style={{ width: '100%', accentColor: '#6366f1' }}
1192
+ />
1193
+ </div>
1194
+
1195
+ {/* Glass Opacity */}
1196
+ {settings.glass && (
1197
+ <div style={{ marginBottom: '16px' }}>
1198
+ <label style={{ display: 'block', marginBottom: '6px', fontWeight: '500' }}>
1199
+ Glass Opacity ({settings.glassOpacity})
1200
+ </label>
1201
+ <input
1202
+ type="range"
1203
+ min="0"
1204
+ max="1"
1205
+ step="0.05"
1206
+ value={settings.glassOpacity}
1207
+ onChange={e => handleChange('glassOpacity', parseFloat(e.target.value))}
1208
+ style={{ width: '100%', accentColor: '#6366f1' }}
1209
+ />
1210
+ </div>
1211
+ )}
1212
+
1213
+ {/* Checkboxes */}
1214
+ {[
1215
+ { key: 'autoplay', label: 'Autoplay' },
1216
+ { key: 'muted', label: 'Muted' },
1217
+ { key: 'loop', label: 'Loop' },
1218
+ { key: 'controls', label: 'Controls' },
1219
+ { key: 'showDownload', label: 'Download Button' },
1220
+ { key: 'showShare', label: 'Share Button' },
1221
+ { key: 'showSettings', label: 'Settings Menu' },
1222
+ { key: 'ambientMode', label: 'Ambient Mode' },
1223
+ { key: 'glass', label: 'Glass Effect' },
1224
+ ].map(({ key, label }) => (
1225
+ <div
1226
+ key={key}
1227
+ style={{ display: 'flex', alignItems: 'center', marginBottom: '12px', gap: '8px' }}
1228
+ >
1229
+ <input
1230
+ type="checkbox"
1231
+ id={key}
1232
+ checked={settings[key as keyof typeof settings] as boolean}
1233
+ onChange={e => handleChange(key, e.target.checked)}
1234
+ style={{ width: '16px', height: '16px' }}
1235
+ />
1236
+ <label htmlFor={key} style={{ fontSize: '13px' }}>
1237
+ {label}
1238
+ </label>
1239
+ </div>
1240
+ ))}
1241
+ </div>
1242
+
1243
+ {/* Video Player */}
1244
+ <div
1245
+ style={{
1246
+ display: 'flex',
1247
+ justifyContent: 'center',
1248
+ alignItems: 'center',
1249
+ height: '100%',
1250
+ paddingLeft: '340px',
1251
+ }}
1252
+ >
1253
+ <VideoPlayer
1254
+ src={videoSources.subaru.src}
1255
+ poster={videoSources.subaru.poster}
1256
+ width="700px"
1257
+ aspectRatio={settings.aspectRatio}
1258
+ autoplay={settings.autoplay}
1259
+ muted={settings.muted}
1260
+ loop={settings.loop}
1261
+ controls={settings.controls}
1262
+ showDownload={settings.showDownload}
1263
+ showShare={settings.showShare}
1264
+ showSettings={settings.showSettings}
1265
+ ambientMode={settings.ambientMode}
1266
+ glass={settings.glass}
1267
+ glassOpacity={settings.glassOpacity}
1268
+ quality={sampleQualities}
1269
+ subtitles={sampleSubtitles}
1270
+ onPlay={fn()}
1271
+ onPause={fn()}
1272
+ onEnded={fn()}
1273
+ onTimeUpdate={fn()}
1274
+ onVolumeChange={fn()}
1275
+ onFullscreenChange={fn()}
1276
+ onError={fn()}
1277
+ />
1278
+ </div>
1279
+ </BackgroundWrapper>
1280
+ );
1281
+ },
1282
+ parameters: {
1283
+ docs: {
1284
+ description: {
1285
+ story:
1286
+ 'Interactive playground allowing real-time experimentation with all VideoPlayer properties. Use the control panel to adjust settings and see how they affect the player appearance and behavior.',
473
1287
  },
474
- ],
475
- showSettings: true,
476
- onPlay: fn(),
477
- onPause: fn(),
478
- onEnded: fn(),
479
- onTimeUpdate: fn(),
480
- onVolumeChange: fn(),
481
- onFullscreenChange: fn(),
482
- onError: fn(),
1288
+ },
483
1289
  },
484
1290
  };