@shohojdhara/atomix 0.2.3 → 0.2.5

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 (225) hide show
  1. package/README.md +19 -0
  2. package/dist/atomix.css +1703 -1544
  3. package/dist/atomix.min.css +4 -4
  4. package/dist/index.d.ts +1465 -963
  5. package/dist/index.esm.js +16289 -25908
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +15650 -21780
  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/applemix.css +15008 -0
  12. package/dist/themes/applemix.min.css +72 -0
  13. package/dist/themes/boomdevs.css +1608 -1450
  14. package/dist/themes/boomdevs.min.css +5 -5
  15. package/dist/themes/esrar.css +1702 -1543
  16. package/dist/themes/esrar.min.css +4 -4
  17. package/dist/themes/flashtrade.css +15159 -0
  18. package/dist/themes/flashtrade.min.css +86 -0
  19. package/dist/themes/mashroom.css +1699 -1540
  20. package/dist/themes/mashroom.min.css +7 -7
  21. package/dist/themes/shaj-default.css +1693 -1534
  22. package/dist/themes/shaj-default.min.css +4 -4
  23. package/package.json +6 -17
  24. package/src/components/Accordion/Accordion.stories.tsx +662 -21
  25. package/src/components/Accordion/Accordion.tsx +21 -14
  26. package/src/components/AtomixGlass/AtomixGlass.test.tsx +106 -72
  27. package/src/components/AtomixGlass/AtomixGlass.tsx +529 -1195
  28. package/src/components/AtomixGlass/AtomixGlassContainer.tsx +400 -0
  29. package/src/components/AtomixGlass/GlassFilter.tsx +156 -0
  30. package/src/components/AtomixGlass/README.md +124 -2
  31. package/src/components/AtomixGlass/atomixGLass.old.tsx +1266 -0
  32. package/src/components/AtomixGlass/glass-utils.ts +263 -0
  33. package/src/components/AtomixGlass/shader-utils.ts +792 -68
  34. package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1250 -0
  35. package/src/components/AtomixGlass/stories/Examples.stories.tsx +5768 -0
  36. package/src/components/AtomixGlass/stories/Modes.stories.tsx +1065 -0
  37. package/src/components/AtomixGlass/stories/Playground.stories.tsx +1129 -0
  38. package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +395 -0
  39. package/src/components/AtomixGlass/stories/shared-components.tsx +301 -0
  40. package/src/components/AtomixGlass/utils.ts +3 -3
  41. package/src/components/Avatar/Avatar.tsx +3 -0
  42. package/src/components/Avatar/AvatarGroup.tsx +2 -1
  43. package/src/components/Badge/Badge.stories.tsx +76 -55
  44. package/src/components/Badge/Badge.tsx +12 -14
  45. package/src/components/Breadcrumb/Breadcrumb.tsx +23 -4
  46. package/src/components/Button/Button.stories.tsx +501 -20
  47. package/src/components/Button/Button.tsx +5 -8
  48. package/src/components/Callout/Callout.stories.tsx +86 -35
  49. package/src/components/Callout/Callout.tsx +31 -9
  50. package/src/components/Card/Card.stories.tsx +565 -2
  51. package/src/components/Card/Card.tsx +15 -4
  52. package/src/components/Card/ElevationCard.tsx +2 -0
  53. package/src/components/Chart/AnimatedChart.tsx +179 -156
  54. package/src/components/Chart/AreaChart.tsx +123 -12
  55. package/src/components/Chart/BarChart.tsx +91 -100
  56. package/src/components/Chart/BaseChart.tsx +80 -0
  57. package/src/components/Chart/BubbleChart.tsx +114 -290
  58. package/src/components/Chart/CandlestickChart.tsx +282 -622
  59. package/src/components/Chart/Chart.stories.tsx +576 -179
  60. package/src/components/Chart/Chart.tsx +374 -75
  61. package/src/components/Chart/ChartRenderer.tsx +371 -220
  62. package/src/components/Chart/ChartToolbar.tsx +372 -61
  63. package/src/components/Chart/ChartTooltip.tsx +33 -18
  64. package/src/components/Chart/DonutChart.tsx +172 -254
  65. package/src/components/Chart/FunnelChart.tsx +169 -240
  66. package/src/components/Chart/GaugeChart.tsx +224 -392
  67. package/src/components/Chart/HeatmapChart.tsx +302 -440
  68. package/src/components/Chart/LineChart.tsx +148 -103
  69. package/src/components/Chart/MultiAxisChart.tsx +267 -395
  70. package/src/components/Chart/PieChart.tsx +114 -64
  71. package/src/components/Chart/RadarChart.tsx +202 -218
  72. package/src/components/Chart/ScatterChart.tsx +111 -97
  73. package/src/components/Chart/TreemapChart.tsx +147 -222
  74. package/src/components/Chart/WaterfallChart.tsx +253 -291
  75. package/src/components/Chart/index.ts +11 -9
  76. package/src/components/Chart/types.ts +85 -9
  77. package/src/components/Chart/utils.ts +66 -0
  78. package/src/components/ColorModeToggle/ColorModeToggle.tsx +6 -3
  79. package/src/components/Countdown/Countdown.tsx +4 -0
  80. package/src/components/DataTable/DataTable.tsx +2 -1
  81. package/src/components/DatePicker/DatePicker.stories.tsx +689 -12
  82. package/src/components/DatePicker/DatePicker.tsx +3 -9
  83. package/src/components/DatePicker/types.ts +5 -0
  84. package/src/components/Dropdown/Dropdown.stories.tsx +32 -25
  85. package/src/components/Dropdown/Dropdown.tsx +26 -28
  86. package/src/components/EdgePanel/EdgePanel.stories.tsx +473 -2
  87. package/src/components/EdgePanel/EdgePanel.tsx +101 -13
  88. package/src/components/Footer/Footer.stories.tsx +187 -60
  89. package/src/components/Footer/Footer.test.tsx +134 -0
  90. package/src/components/Footer/Footer.tsx +133 -34
  91. package/src/components/Footer/FooterLink.tsx +1 -1
  92. package/src/components/Footer/FooterSection.tsx +53 -36
  93. package/src/components/Footer/FooterSocialLink.tsx +32 -29
  94. package/src/components/Footer/README.md +82 -3
  95. package/src/components/Footer/index.ts +1 -1
  96. package/src/components/Form/Checkbox.stories.tsx +13 -5
  97. package/src/components/Form/Checkbox.tsx +3 -6
  98. package/src/components/Form/Form.stories.tsx +10 -3
  99. package/src/components/Form/Form.tsx +2 -0
  100. package/src/components/Form/FormGroup.tsx +2 -1
  101. package/src/components/Form/Input.stories.tsx +12 -11
  102. package/src/components/Form/Input.tsx +97 -95
  103. package/src/components/Form/Radio.stories.tsx +22 -7
  104. package/src/components/Form/Radio.tsx +3 -6
  105. package/src/components/Form/Select.stories.tsx +21 -6
  106. package/src/components/Form/Select.tsx +3 -5
  107. package/src/components/Form/Textarea.stories.tsx +13 -11
  108. package/src/components/Form/Textarea.tsx +88 -86
  109. package/src/components/Hero/Hero.stories.tsx +2 -3
  110. package/src/components/Hero/Hero.tsx +5 -6
  111. package/src/components/Icon/Icon.tsx +12 -1
  112. package/src/components/List/List.tsx +2 -1
  113. package/src/components/List/ListGroup.tsx +2 -1
  114. package/src/components/Messages/Messages.stories.tsx +113 -0
  115. package/src/components/Messages/Messages.tsx +52 -9
  116. package/src/components/Modal/Modal.stories.tsx +48 -32
  117. package/src/components/Modal/Modal.tsx +19 -24
  118. package/src/components/Navigation/Menu/MegaMenu.tsx +2 -2
  119. package/src/components/Navigation/Menu/Menu.tsx +2 -2
  120. package/src/components/Navigation/Nav/Nav.stories.tsx +469 -0
  121. package/src/components/Navigation/Nav/Nav.tsx +22 -4
  122. package/src/components/Navigation/Nav/NavDropdown.tsx +10 -1
  123. package/src/components/Navigation/Navbar/Navbar.stories.tsx +413 -0
  124. package/src/components/Navigation/Navbar/Navbar.tsx +70 -29
  125. package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +340 -0
  126. package/src/components/Navigation/SideMenu/SideMenu.tsx +29 -2
  127. package/src/components/Pagination/Pagination.stories.tsx +13 -6
  128. package/src/components/Pagination/Pagination.tsx +7 -6
  129. package/src/components/PhotoViewer/PhotoViewer.tsx +2 -1
  130. package/src/components/Popover/Popover.stories.tsx +32 -24
  131. package/src/components/Popover/Popover.tsx +4 -1
  132. package/src/components/ProductReview/ProductReview.tsx +8 -2
  133. package/src/components/Progress/Progress.tsx +19 -3
  134. package/src/components/Rating/Rating.stories.tsx +11 -6
  135. package/src/components/Rating/Rating.tsx +3 -5
  136. package/src/components/River/River.tsx +5 -5
  137. package/src/components/SectionIntro/SectionIntro.tsx +8 -2
  138. package/src/components/Slider/Slider.stories.tsx +4 -4
  139. package/src/components/Slider/Slider.tsx +4 -3
  140. package/src/components/Spinner/Spinner.tsx +19 -3
  141. package/src/components/Steps/Steps.stories.tsx +5 -4
  142. package/src/components/Steps/Steps.tsx +8 -5
  143. package/src/components/Tab/Tab.stories.tsx +4 -3
  144. package/src/components/Tab/Tab.tsx +8 -6
  145. package/src/components/Testimonial/Testimonial.tsx +8 -2
  146. package/src/components/Todo/Todo.tsx +2 -1
  147. package/src/components/Toggle/Toggle.stories.tsx +5 -4
  148. package/src/components/Toggle/Toggle.tsx +8 -5
  149. package/src/components/Tooltip/Tooltip.stories.tsx +40 -30
  150. package/src/components/Tooltip/Tooltip.tsx +9 -2
  151. package/src/components/Upload/Upload.stories.tsx +252 -0
  152. package/src/components/Upload/Upload.tsx +92 -53
  153. package/src/components/VideoPlayer/VideoPlayer.tsx +3 -1
  154. package/src/components/index.ts +0 -4
  155. package/src/layouts/Grid/Grid.stories.tsx +10 -23
  156. package/src/layouts/Grid/Grid.tsx +20 -1
  157. package/src/layouts/Grid/GridCol.tsx +76 -48
  158. package/src/lib/composables/useAtomixGlass.ts +861 -44
  159. package/src/lib/composables/useBarChart.ts +21 -4
  160. package/src/lib/composables/useChart.ts +227 -370
  161. package/src/lib/composables/useChartExport.ts +19 -78
  162. package/src/lib/composables/useChartToolbar.ts +11 -21
  163. package/src/lib/composables/useEdgePanel.ts +125 -71
  164. package/src/lib/composables/useFooter.ts +3 -3
  165. package/src/lib/composables/useGlassContainer.ts +16 -7
  166. package/src/lib/composables/useLineChart.ts +11 -2
  167. package/src/lib/composables/usePieChart.ts +4 -14
  168. package/src/lib/composables/useRiver.ts +5 -0
  169. package/src/lib/composables/useSlider.ts +62 -24
  170. package/src/lib/composables/useVideoPlayer.ts +60 -63
  171. package/src/lib/constants/components.ts +147 -32
  172. package/src/lib/types/components.ts +355 -25
  173. package/src/lib/utils/displacement-generator.ts +55 -49
  174. package/src/lib/utils/icons.ts +1 -1
  175. package/src/lib/utils/index.ts +16 -10
  176. package/src/styles/01-settings/_settings.accordion.scss +19 -19
  177. package/src/styles/01-settings/_settings.animations.scss +5 -5
  178. package/src/styles/01-settings/_settings.avatar-group.scss +1 -1
  179. package/src/styles/01-settings/_settings.avatar.scss +17 -17
  180. package/src/styles/01-settings/_settings.background.scss +0 -3
  181. package/src/styles/01-settings/_settings.badge.scss +1 -1
  182. package/src/styles/01-settings/_settings.breadcrumb.scss +1 -1
  183. package/src/styles/01-settings/_settings.card.scss +1 -1
  184. package/src/styles/01-settings/_settings.chart.scss +65 -2
  185. package/src/styles/01-settings/_settings.dropdown.scss +1 -1
  186. package/src/styles/01-settings/_settings.edge-panel.scss +1 -1
  187. package/src/styles/01-settings/_settings.footer.scss +35 -42
  188. package/src/styles/01-settings/_settings.input.scss +1 -1
  189. package/src/styles/01-settings/_settings.list.scss +1 -1
  190. package/src/styles/01-settings/_settings.rating.scss +1 -1
  191. package/src/styles/01-settings/_settings.tabs.scss +1 -1
  192. package/src/styles/01-settings/_settings.upload.scss +6 -5
  193. package/src/styles/02-tools/_tools.animations.scss +4 -5
  194. package/src/styles/02-tools/_tools.background.scss +1 -13
  195. package/src/styles/02-tools/_tools.glass.scss +0 -1
  196. package/src/styles/02-tools/_tools.utility-api.scss +91 -48
  197. package/src/styles/03-generic/_generic.root.scss +1 -4
  198. package/src/styles/04-elements/_elements.body.scss +0 -1
  199. package/src/styles/06-components/_components.atomix-glass.scss +249 -0
  200. package/src/styles/06-components/_components.badge.scss +8 -23
  201. package/src/styles/06-components/_components.button.scss +8 -3
  202. package/src/styles/06-components/_components.callout.scss +10 -5
  203. package/src/styles/06-components/_components.card.scss +2 -14
  204. package/src/styles/06-components/_components.chart.scss +969 -1449
  205. package/src/styles/06-components/_components.dropdown.scss +19 -7
  206. package/src/styles/06-components/_components.edge-panel.scss +103 -0
  207. package/src/styles/06-components/_components.footer.scss +166 -85
  208. package/src/styles/06-components/_components.input.scss +8 -9
  209. package/src/styles/06-components/_components.list.scss +1 -0
  210. package/src/styles/06-components/_components.messages.scss +176 -0
  211. package/src/styles/06-components/_components.modal.scss +16 -4
  212. package/src/styles/06-components/_components.navbar.scss +12 -1
  213. package/src/styles/06-components/_components.side-menu.scss +5 -0
  214. package/src/styles/06-components/_components.skeleton.scss +8 -6
  215. package/src/styles/06-components/_components.upload.scss +219 -4
  216. package/src/styles/06-components/old.chart.styles.scss +1 -30
  217. package/src/styles/99-utilities/_index.scss +1 -0
  218. package/src/styles/99-utilities/_utilities.glass-fixes.scss +1 -0
  219. package/src/styles/99-utilities/_utilities.scss +1 -1
  220. package/src/components/AtomixGlass/AtomixGlass.stories.tsx +0 -3011
  221. package/src/components/AtomixGlass/AtomixGlassComprehensivePreview.stories.tsx +0 -1369
  222. package/src/components/Chart/AdvancedChart.tsx +0 -624
  223. package/src/components/Chart/LineChartNew.tsx +0 -167
  224. package/src/components/Chart/RealTimeChart.tsx +0 -436
  225. package/src/components/DatePicker/DatePicker copy.tsx +0 -551
@@ -1,3011 +0,0 @@
1
- /**
2
- * AtomixGlass.stories.tsx
3
- *
4
- * This file contains comprehensive Storybook stories for the AtomixGlass component, showcasing
5
- * various use cases, configurations, and best practices. The stories demonstrate
6
- * the component's versatility and provide examples for developers to reference.
7
- *\
8
- * @package Atomix
9
- * @component AtomixGlass
10
- */
11
-
12
- import { Meta, StoryObj } from '@storybook/react';
13
- import AtomixGlass from './AtomixGlass';
14
- import Button from '../Button/Button';
15
- import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
16
- import React from 'react';
17
- import type { RefObject } from 'react';
18
-
19
- /**
20
- * Storybook meta configuration for AtomixGlass component
21
- *
22
- * This defines the component's metadata, documentation, and controls
23
- * for the Storybook interface.
24
- */
25
- const meta: Meta<typeof AtomixGlass> = {
26
- title: 'Components/AtomixGlass',
27
- component: AtomixGlass,
28
- parameters: {
29
- layout: 'centered',
30
- docs: {
31
- description: {
32
- component:
33
- 'A glass-like component with chromatic aberration and displacement effects. The component provides a modern, frosted glass aesthetic with interactive hover effects. This component is ideal for creating modern UI elements with depth and visual interest.',
34
- },
35
- },
36
- },
37
- tags: ['autodocs'],
38
- argTypes: {
39
- children: {
40
- control: 'text',
41
- description: 'Content to display inside the glass effect',
42
- },
43
- displacementScale: {
44
- control: { type: 'range', min: 0, max: 100, step: 1 },
45
- description: 'Displacement scale for the glass effect (default: 70)',
46
- table: { defaultValue: { summary: '70' } },
47
- },
48
- blurAmount: {
49
- control: { type: 'range', min: 0, max: 10, step: 0.5 },
50
- description: 'Blur amount for the backdrop (default: 0.0625)',
51
- table: { defaultValue: { summary: '0.0625' } },
52
- },
53
- saturation: {
54
- control: { type: 'range', min: 100, max: 300, step: 5 },
55
- description: 'Saturation percentage for the backdrop (default: 140)',
56
- table: { defaultValue: { summary: '140' } },
57
- },
58
- aberrationIntensity: {
59
- control: { type: 'range', min: 0, max: 10, step: 0.1 },
60
- description: 'Chromatic aberration intensity (default: 2)',
61
- table: { defaultValue: { summary: '2' } },
62
- },
63
- elasticity: {
64
- control: { type: 'range', min: 0, max: 1, step: 0.01 },
65
- description: 'Elasticity factor for mouse interactions (default: 0.15)',
66
- table: { defaultValue: { summary: '0.15' } },
67
- },
68
- cornerRadius: {
69
- control: { type: 'range', min: 0, max: 50, step: 1 },
70
- description: 'Corner radius in pixels (default: 20)',
71
- table: { defaultValue: { summary: '20' } },
72
- },
73
- globalMousePos: {
74
- control: 'object',
75
- description: 'External global mouse position { x: number; y: number }',
76
- },
77
- mouseOffset: {
78
- control: 'object',
79
- description: 'External mouse offset { x: number; y: number }',
80
- },
81
- mouseContainer: {
82
- control: false,
83
- description: 'React ref object for mouse container element',
84
- },
85
- padding: {
86
- control: 'text',
87
- description: 'Padding for the glass container (default: "0 0")',
88
- table: { defaultValue: { summary: '"0 0"' } },
89
- },
90
- overLight: {
91
- control: 'boolean',
92
- description: 'Whether the glass is over a light background (default: false)',
93
- table: { defaultValue: { summary: 'false' } },
94
- },
95
- mode: {
96
- control: 'select',
97
- options: ['standard', 'polar', 'prominent', 'shader'],
98
- description: 'Glass effect mode (default: "standard")',
99
- table: { defaultValue: { summary: '"standard"' } },
100
- },
101
- onClick: {
102
- action: 'clicked',
103
- description: 'Click event handler',
104
- },
105
- className: {
106
- control: 'text',
107
- description: 'Additional CSS class names',
108
- },
109
- style: {
110
- control: 'object',
111
- description: 'CSS style object',
112
- },
113
- 'aria-label': {
114
- control: 'text',
115
- description: 'ARIA label for accessibility',
116
- },
117
- 'aria-describedby': {
118
- control: 'text',
119
- description: 'ARIA describedby attribute for accessibility',
120
- },
121
- role: {
122
- control: 'text',
123
- description: 'ARIA role attribute',
124
- },
125
- tabIndex: {
126
- control: 'number',
127
- description: 'Tab index for keyboard navigation',
128
- },
129
- reducedMotion: {
130
- control: 'boolean',
131
- description: 'Override for reduced motion preference (default: false)',
132
- table: { defaultValue: { summary: 'false' } },
133
- },
134
- highContrast: {
135
- control: 'boolean',
136
- description: 'Override for high contrast preference (default: false)',
137
- table: { defaultValue: { summary: 'false' } },
138
- },
139
- disableEffects: {
140
- control: 'boolean',
141
- description: 'Disable all visual effects (default: false)',
142
- table: { defaultValue: { summary: 'false' } },
143
- },
144
- enablePerformanceMonitoring: {
145
- control: 'boolean',
146
- description: 'Enable performance monitoring (default: false)',
147
- table: { defaultValue: { summary: 'false' } },
148
- },
149
- },
150
- };
151
-
152
- export default meta;
153
- type Story = StoryObj<typeof AtomixGlass>;
154
-
155
- /**
156
- * Enhanced BackgroundWrapper Component
157
- *
158
- * A utility component used throughout the stories to provide consistent background
159
- * styling and overlay effects. This wrapper creates a visually appealing container
160
- * for showcasing the AtomixGlass component in various scenarios.
161
- *
162
- * @component BackgroundWrapper
163
- */
164
- interface BackgroundWrapperProps {
165
- /** Child elements to render inside the wrapper */
166
- children: React.ReactNode;
167
- /** Background image URL or index from the backgroundImages array */
168
- backgroundImage?: string;
169
- /** Background index to use from the predefined array */
170
- backgroundIndex?: number;
171
- /** Optional overlay flag for quick overlay application */
172
- overlay?: boolean;
173
- /** Custom overlay color in CSS format */
174
- overlayColor?: string;
175
- /** Overlay opacity (0-1) */
176
- overlayOpacity?: number;
177
- /** Container height */
178
- height?: string;
179
- /** Container width */
180
- width?: string;
181
- /** Container border radius */
182
- borderRadius?: string;
183
- /** Container padding */
184
- padding?: string;
185
- /** Additional CSS class names */
186
- className?: string;
187
- /** Additional inline styles */
188
- style?: React.CSSProperties;
189
- /** Enable interactive background movement */
190
- interactive?: boolean;
191
- }
192
-
193
- /**
194
- * Interactive Story Container
195
- *
196
- * A container that provides mouse tracking and interactive background effects
197
- * for enhanced storytelling and demonstration purposes.
198
- */
199
- interface StoryContainerProps {
200
- children: React.ReactNode;
201
- style?: React.CSSProperties;
202
- interactive?: boolean;
203
- }
204
-
205
- /**
206
- * Interactive Wrapper Component
207
- *
208
- * Provides mouse position tracking and offset calculations for interactive stories
209
- */
210
- interface InteractiveWrapperProps {
211
- children: (
212
- mousePos: { x: number; y: number },
213
- mouseOffset: { x: number; y: number },
214
- containerRef: RefObject<HTMLDivElement>
215
- ) => React.ReactNode;
216
- }
217
-
218
- /**
219
- * BackgroundWrapper Component Implementation
220
- *
221
- * Renders a container with a background image and optional overlay,
222
- * providing a consistent environment for showcasing the AtomixGlass component.
223
- *
224
- * @param props - BackgroundWrapperProps
225
- * @returns JSX.Element
226
- */
227
- const BackgroundWrapper = ({
228
- children,
229
- backgroundImage,
230
- backgroundIndex,
231
- overlay = false,
232
- overlayColor = 'rgba(0,0,0,0)',
233
- overlayOpacity = 0,
234
- height = '90vh',
235
- width = '90vw',
236
- borderRadius = '12px',
237
- padding = '24px',
238
- className = '',
239
- style = {},
240
- }: BackgroundWrapperProps) => {
241
- // If backgroundIndex is provided, use it to select from the backgroundImages array
242
- const bgImage =
243
- backgroundIndex !== undefined ? backgroundImages[backgroundIndex] : backgroundImage;
244
-
245
- // Apply default overlay settings if overlay flag is true
246
- const finalOverlayColor = overlay ? 'rgba(0,0,0,0.5)' : overlayColor;
247
- const finalOverlayOpacity = overlay ? 0.5 : overlayOpacity;
248
-
249
- return (
250
- <div
251
- className={`atomix-glass-background ${className}`}
252
- style={{
253
- position: 'relative',
254
- width: width,
255
- minHeight: height,
256
- height: '100%',
257
- backgroundImage: bgImage ? `url(${bgImage})` : undefined,
258
- backgroundColor: !bgImage ? '#1a1a2e' : undefined, // Fallback color if no image
259
- backgroundSize: 'cover',
260
- backgroundPosition: 'center',
261
- backgroundAttachment: 'fixed',
262
- display: 'flex',
263
- alignItems: 'center',
264
- justifyContent: 'center',
265
- borderRadius: borderRadius,
266
- padding: padding,
267
- ...style,
268
- }}
269
- >
270
- {/* Overlay for better contrast and visual appeal */}
271
- {finalOverlayOpacity > 0 && (
272
- <div
273
- style={{
274
- position: 'absolute',
275
- top: 0,
276
- left: 0,
277
- right: 0,
278
- bottom: 0,
279
- backgroundColor: finalOverlayColor,
280
- opacity: finalOverlayOpacity,
281
- zIndex: -1,
282
- }}
283
- />
284
- )}
285
- <div
286
- style={{
287
- position: 'relative',
288
- width: '100%',
289
- height: '100%',
290
- display: 'flex',
291
- alignItems: 'center',
292
- justifyContent: 'center',
293
- }}
294
- >
295
- {children}
296
- </div>
297
- </div>
298
- );
299
- };
300
-
301
- /**
302
- * Interactive Story Container Component
303
- *
304
- * A container that provides mouse tracking and interactive background effects
305
- * for enhanced storytelling and demonstration purposes.
306
- */
307
- const StoryContainer = ({ children, style = {}, interactive = false }: StoryContainerProps) => {
308
- const containerRef = useRef<HTMLDivElement>(null);
309
- const [backgroundPosition, setBackgroundPosition] = useState({ x: 0, y: 0 });
310
-
311
- const handleMouseMove = useCallback(
312
- (e: MouseEvent) => {
313
- if (containerRef.current && interactive) {
314
- const rect = containerRef.current.getBoundingClientRect();
315
- const centerX = rect.left + rect.width / 2;
316
- const centerY = rect.top + rect.height / 2;
317
-
318
- // Calculate offset as a percentage
319
- const offsetX = ((e.clientX - centerX) / rect.width) * 100;
320
- const offsetY = ((e.clientY - centerY) / rect.height) * 100;
321
-
322
- setBackgroundPosition({ x: offsetX, y: offsetY });
323
- }
324
- },
325
- [interactive]
326
- );
327
-
328
- useEffect(() => {
329
- const currentRef = containerRef.current;
330
- if (currentRef && interactive) {
331
- currentRef.addEventListener('mousemove', handleMouseMove);
332
- return () => {
333
- currentRef.removeEventListener('mousemove', handleMouseMove);
334
- };
335
- }
336
- }, [handleMouseMove, interactive]);
337
-
338
- return (
339
- <div
340
- ref={containerRef}
341
- style={{
342
- width: '100vw',
343
- height: '100vh',
344
- display: 'flex',
345
- alignItems: 'center',
346
- justifyContent: 'center',
347
- backgroundImage: interactive
348
- ? 'url(https://images.unsplash.com/photo-1497366216548-37526070297c?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)'
349
- : undefined,
350
- backgroundSize: interactive ? '160%' : 'cover',
351
- backgroundPosition: interactive
352
- ? `calc(50% + ${backgroundPosition.x}px) calc(50% + ${backgroundPosition.y}px)`
353
- : 'center',
354
- ...style,
355
- }}
356
- >
357
- {children}
358
- </div>
359
- );
360
- };
361
-
362
- /**
363
- * Interactive Wrapper Component
364
- *
365
- * Provides mouse position tracking and offset calculations for interactive stories
366
- */
367
- const InteractiveWrapper = ({ children }: InteractiveWrapperProps) => {
368
- const containerRef = useRef<HTMLDivElement>(null);
369
- const [mousePos, setMousePos] = useState({ x: 0, y: 0 });
370
- const [mouseOffset, setMouseOffset] = useState({ x: 0, y: 0 });
371
-
372
- const handleMouseMove = useCallback((e: MouseEvent) => {
373
- if (containerRef.current) {
374
- const rect = containerRef.current.getBoundingClientRect();
375
- const centerX = rect.left + rect.width / 2;
376
- const centerY = rect.top + rect.height / 2;
377
-
378
- setMouseOffset({
379
- x: ((e.clientX - centerX) / rect.width) * 100,
380
- y: ((e.clientY - centerY) / rect.height) * 100,
381
- });
382
- }
383
- setMousePos({ x: e.clientX, y: e.clientY });
384
- }, []);
385
-
386
- useEffect(() => {
387
- const currentRef = containerRef.current;
388
- currentRef?.addEventListener('mousemove', handleMouseMove);
389
- return () => {
390
- currentRef?.removeEventListener('mousemove', handleMouseMove);
391
- };
392
- }, [handleMouseMove]);
393
-
394
- return (
395
- <div ref={containerRef} style={{ width: '100%', height: '100%' }}>
396
- {children(mousePos, mouseOffset, containerRef)}
397
- </div>
398
- );
399
- };
400
-
401
- /**
402
- * Collection of high-quality background images for different moods and scenarios
403
- *
404
- * This array provides a variety of background options that work well with the
405
- * AtomixGlass component, showcasing different visual styles and contexts.
406
- */
407
- const backgroundImages = [
408
- // 0: Modern office interior with natural lighting
409
- 'https://images.pexels.com/photos/5653101/pexels-photo-5653101.jpeg',
410
- // 1: Beautiful natural landscape - mountains and lake
411
- 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
412
- // 2: Urban cityscape with modern buildings
413
- 'https://images.unsplash.com/photo-1477959858617-67f85cf4f1df?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
414
- // 3: Forest path with sunlight filtering through trees
415
- 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
416
- // 4: Ocean waves and beach scene
417
- 'https://images.unsplash.com/photo-1505142468610-359e7d316be0?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
418
- // 5: Modern architecture with glass facades
419
- 'https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
420
- // 6: Cozy café interior with warm lighting
421
- 'https://images.unsplash.com/photo-1554118811-1e0d58224f24?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
422
- // 7: Desert landscape with dramatic sky
423
- 'https://images.unsplash.com/photo-1509316785289-025f5b846b35?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
424
- // 8: Tropical paradise with palm trees and ocean
425
- 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
426
- // 9: Modern library or workspace with natural light
427
- 'https://images.unsplash.com/photo-1521587760476-6c12a4b040da?q=80&w=2940&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
428
- ];
429
-
430
- /**
431
- * Legacy backgrounds object for backward compatibility
432
- * @deprecated Use backgroundImages array instead
433
- */
434
- const backgrounds = {
435
- // Office and workspace environments
436
- blueGradient: backgroundImages[0], // Modern office interior
437
- purpleGradient: backgroundImages[1], // Mountain landscape
438
- greenGradient: backgroundImages[3], // Forest path
439
-
440
- // Apple-inspired natural scenes
441
- macosWallpaper: backgroundImages[1], // Mountain landscape
442
- iosWallpaper: backgroundImages[4], // Ocean waves
443
-
444
- // Nature scenes
445
- mountains: backgroundImages[1], // Mountain landscape
446
- ocean: backgroundImages[4], // Ocean waves
447
-
448
- // Urban environments
449
- cityNight: backgroundImages[2], // Urban cityscape
450
- cityDay: backgroundImages[5], // Modern architecture
451
-
452
- // Interior spaces
453
- abstract1: backgroundImages[6], // Cozy café interior
454
- abstract2: backgroundImages[9], // Modern library
455
-
456
- // Video backgrounds
457
- videoBackground:
458
- 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
459
- };
460
-
461
- /**
462
- * Default showcase of the AtomixGlass component
463
- *
464
- * This story demonstrates the default configuration of the AtomixGlass component
465
- * with carefully selected parameters to achieve an optimal glass effect. It serves
466
- * as a reference implementation with balanced settings suitable for most use cases.
467
- *
468
- * Key features demonstrated:
469
- * - Balanced displacement scale for subtle distortion
470
- * - Moderate blur amount for the frosted glass effect
471
- * - Enhanced saturation for visual appeal
472
- * - Subtle chromatic aberration for depth
473
- * - Interactive hover effects for engagement
474
- */
475
- export const Default: Story = {
476
- args: {
477
- children: (
478
- <div style={{ padding: '30px', textAlign: 'center', maxWidth: '400px' }}>
479
- <h2 style={{ margin: '0 0 16px 0', fontSize: '24px', fontWeight: 600 }}>AtomixGlass</h2>
480
- <p style={{ margin: '0 0 20px 0', fontSize: '16px', lineHeight: 1.6 }}>
481
- A premium glass morphism component with realistic light refraction, chromatic aberration,
482
- and interactive effects.
483
- </p>
484
- <div style={{ display: 'flex', justifyContent: 'center', gap: '12px', flexWrap: 'wrap' }}>
485
- <button className="c-btn c-btn--primary">Explore</button>
486
- <button className="c-btn c-btn--outline-light">Learn More</button>
487
- </div>
488
- </div>
489
- ),
490
- displacementScale: 15, // Using component default
491
- blurAmount: 1, // Using component default
492
- saturation: 140, // Using component default
493
- aberrationIntensity: 2, // Using component default
494
- elasticity: 0.15, // Using component default
495
- cornerRadius: 20, // Using component default
496
- padding: '0 0', // Using component default
497
- overLight: false, // Using component default
498
- mode: 'standard', // Using component default
499
- },
500
- decorators: [
501
- Story => (
502
- <BackgroundWrapper
503
- backgroundImage={backgrounds.blueGradient}
504
- height="70vh"
505
- width="90vw"
506
- overlayOpacity={0.1}
507
- overlayColor="rgba(0,0,0,0.2)"
508
- >
509
- <Story />
510
- </BackgroundWrapper>
511
- ),
512
- ],
513
- parameters: {
514
- docs: {
515
- description: {
516
- story:
517
- 'The default configuration of AtomixGlass with optimal parameters for a realistic glass effect. This component mimics the Apple-style liquid glass UI with chromatic aberration and displacement effects.',
518
- },
519
- },
520
- },
521
- };
522
-
523
- // Interactive demo with controls
524
- export const Interactive: Story = {
525
- render: args => {
526
- // eslint-disable-next-line react-hooks/rules-of-hooks
527
- const [isActive, setIsActive] = useState(false);
528
- // eslint-disable-next-line react-hooks/rules-of-hooks
529
- const [isClicked, setIsClicked] = useState(false);
530
-
531
- return (
532
- <BackgroundWrapper
533
- backgroundImage={backgrounds.purpleGradient}
534
- height="65vh"
535
- overlayOpacity={0.15}
536
- >
537
- <AtomixGlass
538
- {...args}
539
- onClick={() => {
540
- setIsActive(!isActive);
541
- setIsClicked(!isClicked);
542
- }}
543
- >
544
- <div style={{ padding: '30px', textAlign: 'center', minWidth: '300px' }}>
545
- <h3 style={{ margin: '0 0 16px 0', fontSize: '22px', fontWeight: 500 }}>
546
- Interactive Glass
547
- </h3>
548
- <p style={{ margin: '0 0 20px 0', fontSize: '16px', lineHeight: 1.5 }}>
549
- {isClicked
550
- ? 'Thanks for clicking!'
551
- : 'Hover and click to see the interactive effects in action.'}
552
- </p>
553
- <button
554
- className={`c-btn c-btn--${isClicked ? 'success' : 'primary'}`}
555
- style={{ transition: 'all 0.3s ease' }}
556
- >
557
- {isClicked ? 'Clicked!' : 'Click Me'}
558
- </button>
559
- </div>
560
- </AtomixGlass>
561
- </BackgroundWrapper>
562
- );
563
- },
564
- args: {
565
- displacementScale: 15,
566
- blurAmount: 0.0625,
567
- saturation: 200,
568
- aberrationIntensity: 3,
569
- elasticity: 0.2,
570
- cornerRadius: 15,
571
- padding: '0 0',
572
- overLight: false,
573
- mode: 'standard',
574
- },
575
- parameters: {
576
- docs: {
577
- description: {
578
- story:
579
- 'An interactive example that demonstrates the hover and click effects of the AtomixGlass component. Try hovering and clicking to see the glass react to user interactions.',
580
- },
581
- },
582
- },
583
- };
584
-
585
- /**
586
- * Mode Showcase - Demonstrates the visual differences between the various modes
587
- *
588
- * This story showcases all available modes of the AtomixGlass component with
589
- * optimized settings for each mode to highlight their unique characteristics.
590
- */
591
- /**
592
- * ModeShowcase Story
593
- *
594
- * This story demonstrates the different modes available in the AtomixGlass component.
595
- * Each mode provides a unique visual effect with different displacement patterns,
596
- * blur amounts, and aberration intensities. This showcase allows users to compare
597
- * the different modes side by side and understand their visual characteristics.
598
- *
599
- * Modes demonstrated:
600
- * - standard: Balanced displacement and aberration
601
- * - polar: Circular refraction pattern
602
- * - prominent: Enhanced displacement with stronger edge effects
603
- * - shader: Advanced shader-based displacement for maximum visual impact
604
- */
605
- export const ModeShowcase: Story = {
606
- parameters: {
607
- docs: {
608
- description: {
609
- story:
610
- 'Showcases the different modes available in the AtomixGlass component, highlighting their unique visual characteristics.',
611
- },
612
- },
613
- },
614
- render: () => {
615
- // eslint-disable-next-line react-hooks/rules-of-hooks
616
- const [activeMode, setActiveMode] = useState<string | null>(null);
617
- const modes = ['standard', 'polar', 'prominent', 'shader'] as const;
618
-
619
- // Different settings for each mode to highlight their unique characteristics
620
- const modeSettings = {
621
- standard: {
622
- displacementScale: 15,
623
- blurAmount: 0.0625,
624
- saturation: 140,
625
- aberrationIntensity: 2,
626
- description: 'Standard glass effect with balanced displacement and aberration',
627
- color: '#ffffff',
628
- },
629
- polar: {
630
- displacementScale: 15,
631
- blurAmount: 0.05,
632
- saturation: 160,
633
- aberrationIntensity: 2.5,
634
- description: 'Polar displacement creates a circular refraction pattern',
635
- color: '#f0f8ff',
636
- },
637
- prominent: {
638
- displacementScale: 15,
639
- blurAmount: 0.08,
640
- saturation: 180,
641
- aberrationIntensity: 3,
642
- description: 'Enhanced displacement with stronger edge effects',
643
- color: '#ffffff',
644
- },
645
- shader: {
646
- displacementScale: 15,
647
- blurAmount: 0.1,
648
- saturation: 150,
649
- aberrationIntensity: 4,
650
- description: 'Advanced shader-based displacement for maximum visual impact',
651
- color: '#e6f7ff',
652
- },
653
- };
654
-
655
- // Handle mouse enter/leave for cards
656
- const handleMouseEnter = (mode: string) => {
657
- setActiveMode(mode);
658
- };
659
-
660
- const handleMouseLeave = () => {
661
- setActiveMode(null);
662
- };
663
-
664
- return (
665
- <BackgroundWrapper backgroundImage={backgroundImages[2]} height="75vh" overlayOpacity={0.1}>
666
- <div>
667
- <div
668
- style={{
669
- padding: '20px 0',
670
- textAlign: 'center',
671
- marginBottom: '20px',
672
- }}
673
- >
674
- <h2
675
- style={{
676
- margin: '0 0 10px 0',
677
- fontSize: '32px',
678
- fontWeight: 500,
679
- color: '#ffffff',
680
- textShadow: '0 2px 4px rgba(0,0,0,0.2)',
681
- }}
682
- >
683
- AtomixGlass Modes
684
- </h2>
685
- <p
686
- style={{
687
- fontSize: '16px',
688
- maxWidth: '500px',
689
- margin: '0 auto',
690
- color: '#ffffff',
691
- textShadow: '0 1px 2px rgba(0,0,0,0.2)',
692
- }}
693
- >
694
- Hover over each card to see how different modes affect the appearance and behavior of
695
- the glass effect.
696
- </p>
697
- </div>
698
-
699
- <div
700
- style={{
701
- display: 'flex',
702
- flexWrap: 'wrap',
703
- justifyContent: 'center',
704
- alignContent: 'center',
705
- gap: '24px',
706
- width: '70vw',
707
- }}
708
- >
709
- {modes.map(mode => {
710
- const settings = modeSettings[mode];
711
- const isActive = activeMode === mode;
712
-
713
- return (
714
- <AtomixGlass
715
- key={mode}
716
- mode={mode}
717
- displacementScale={settings.displacementScale}
718
- blurAmount={settings.blurAmount}
719
- saturation={settings.saturation}
720
- aberrationIntensity={settings.aberrationIntensity}
721
- elasticity={0.15}
722
- cornerRadius={50}
723
- onClick={() => handleMouseEnter(mode)}
724
- >
725
- <div
726
- style={{
727
- padding: '24px 50px',
728
- textAlign: 'center',
729
- maxWidth: '400px',
730
- minHeight: '200px',
731
- width: '100%',
732
- }}
733
- >
734
- <h3
735
- style={{
736
- margin: '0 0 12px 0',
737
- fontSize: '20px',
738
- fontWeight: 500,
739
- color: settings.color,
740
- }}
741
- >
742
- {mode.charAt(0).toUpperCase() + mode.slice(1)} Mode
743
- </h3>
744
- <p
745
- style={{
746
- margin: '0 0 16px 0',
747
- fontSize: '14px',
748
- lineHeight: 1.5,
749
- color: settings.color,
750
- }}
751
- >
752
- {settings.description}
753
- </p>
754
- <div
755
- style={{
756
- display: 'flex',
757
- justifyContent: 'center',
758
- alignItems: 'center',
759
- gap: '8px',
760
- marginTop: '12px',
761
- flexWrap: 'wrap',
762
- }}
763
- >
764
- <span
765
- style={{
766
- fontSize: '12px',
767
- padding: '4px 8px',
768
- borderRadius: '4px',
769
- background: 'rgba(255,255,255,0.2)',
770
- }}
771
- >
772
- Displacement: {settings.displacementScale}
773
- </span>
774
- <span
775
- style={{
776
- fontSize: '12px',
777
- padding: '4px 8px',
778
- borderRadius: '4px',
779
- background: 'rgba(255,255,255,0.2)',
780
- }}
781
- >
782
- Blur: {settings.blurAmount}
783
- </span>
784
- <span
785
- style={{
786
- fontSize: '12px',
787
- padding: '4px 8px',
788
- borderRadius: '4px',
789
- background: 'rgba(255,255,255,0.2)',
790
- }}
791
- >
792
- Aberration: {settings.aberrationIntensity}
793
- </span>
794
- </div>
795
- </div>
796
- </AtomixGlass>
797
- );
798
- })}
799
- </div>
800
- </div>
801
- </BackgroundWrapper>
802
- );
803
- },
804
- };
805
-
806
- /**
807
- * Apple-inspired UI example showcasing the liquid glass effect
808
- *
809
- * This story demonstrates how to create Apple-like interfaces using the AtomixGlass component,
810
- * mimicking the frosted glass effect seen in macOS and iOS with realistic design elements
811
- * and interactions that closely resemble Apple's design language.
812
- */
813
- export const AppleInspiredUI: Story = {
814
- render: () => {
815
- // eslint-disable-next-line react-hooks/rules-of-hooks
816
- const [activeTab, setActiveTab] = useState('home');
817
- // eslint-disable-next-line react-hooks/rules-of-hooks
818
- const [currentTime, setCurrentTime] = useState('');
819
- // eslint-disable-next-line react-hooks/rules-of-hooks
820
- const [hoverDockItem, setHoverDockItem] = useState<number | null>(null);
821
- // eslint-disable-next-line react-hooks/rules-of-hooks
822
- const [notificationCount, setNotificationCount] = useState(3);
823
-
824
- // eslint-disable-next-line react-hooks/rules-of-hooks
825
- useEffect(() => {
826
- // Update time every minute
827
- const updateTime = () => {
828
- const now = new Date();
829
- const hours = now.getHours();
830
- const minutes = now.getMinutes();
831
- const ampm = hours >= 12 ? 'PM' : 'AM';
832
- const formattedHours = hours % 12 || 12;
833
- const formattedMinutes = minutes < 10 ? `0${minutes}` : minutes;
834
- setCurrentTime(`${formattedHours}:${formattedMinutes} ${ampm}`);
835
- };
836
-
837
- updateTime(); // Initial call
838
- const interval = setInterval(updateTime, 60000);
839
-
840
- return () => clearInterval(interval);
841
- }, []);
842
-
843
- const handleTabChange = (tab: string) => {
844
- setActiveTab(tab);
845
- };
846
-
847
- // Apple-style app icons with gradient backgrounds
848
- const appIcons = [
849
- { name: 'Photos', color: 'linear-gradient(135deg, #FF9500, #FF2D55)', symbol: '📷' },
850
- { name: 'Music', color: 'linear-gradient(135deg, #FF2D55, #AF52DE)', symbol: '🎵' },
851
- { name: 'Mail', color: 'linear-gradient(135deg, #5AC8FA, #007AFF)', symbol: '✉️' },
852
- { name: 'Maps', color: 'linear-gradient(135deg, #34C759, #5AC8FA)', symbol: '🗺️' },
853
- { name: 'Weather', color: 'linear-gradient(135deg, #007AFF, #5AC8FA)', symbol: '☀️' },
854
- { name: 'Notes', color: 'linear-gradient(135deg, #FFCC00, #FF9500)', symbol: '📝' },
855
- ];
856
-
857
- // Dock apps with more realistic icons
858
- const dockApps = [
859
- { name: 'Finder', symbol: '🔍', color: 'linear-gradient(135deg, #1E88E5, #64B5F6)' },
860
- { name: 'Safari', symbol: '🧭', color: 'linear-gradient(135deg, #039BE5, #81D4FA)' },
861
- { name: 'Messages', symbol: '💬', color: 'linear-gradient(135deg, #43A047, #81C784)' },
862
- { name: 'Calendar', symbol: '📅', color: 'linear-gradient(135deg, #E53935, #EF5350)' },
863
- { name: 'Photos', symbol: '🖼️', color: 'linear-gradient(135deg, #8E24AA, #BA68C8)' },
864
- ];
865
-
866
- return (
867
- <BackgroundWrapper
868
- backgroundImage={'https://images.pexels.com/photos/18772443/pexels-photo-18772443.jpeg'}
869
- height="90vh"
870
- style={{ maxWidth: '90vw', padding: '10px' }}
871
- >
872
- {/* Main content area */}
873
- <div
874
- style={{
875
- display: 'flex',
876
- flexDirection: 'column',
877
- alignItems: 'center',
878
- justifyContent: 'space-between',
879
- height: '90vh',
880
- width: '100%',
881
- }}
882
- >
883
- {/* Top menu bar - macOS style with improved design */}
884
-
885
- <AtomixGlass
886
- displacementScale={15}
887
- blurAmount={2}
888
- saturation={150}
889
- aberrationIntensity={0.2}
890
- cornerRadius={8}
891
- mode="shader"
892
- elasticity={0}
893
- >
894
- <div
895
- style={{
896
- padding: '10px 16px',
897
- display: 'flex',
898
- justifyContent: 'space-between',
899
- alignItems: 'center',
900
- width: '77vw',
901
- }}
902
- >
903
- {/* Apple logo and app menu */}
904
- <div style={{ display: 'flex', alignItems: 'center', gap: '20px' }}>
905
- <span
906
- style={{
907
- fontSize: '20px',
908
- fontWeight: 600,
909
- display: 'flex',
910
- alignItems: 'center',
911
- gap: '6px',
912
- }}
913
- >
914
- <span style={{ fontSize: '22px' }}>🍎</span>
915
- <span>Atomix</span>
916
- </span>
917
- <div style={{ display: 'flex', gap: '16px' }}>
918
- {['Finder', 'File', 'Edit', 'View', 'Window', 'Help'].map(tab => (
919
- <button
920
- key={tab}
921
- onClick={() => handleTabChange(tab.toLowerCase())}
922
- style={{
923
- background: 'none',
924
- border: 'none',
925
- padding: '4px 8px',
926
- borderRadius: '4px',
927
- cursor: 'pointer',
928
- backgroundColor:
929
- activeTab === tab.toLowerCase()
930
- ? 'rgba(255,255,255,0.15)'
931
- : 'transparent',
932
- transition: 'all 0.2s ease',
933
- fontSize: '13px',
934
- fontWeight: activeTab === tab.toLowerCase() ? 600 : 400,
935
- color: 'inherit',
936
- }}
937
- >
938
- {tab}
939
- </button>
940
- ))}
941
- </div>
942
- </div>
943
-
944
- {/* Status icons */}
945
- <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
946
- {/* Battery indicator */}
947
- <div
948
- style={{
949
- display: 'flex',
950
- alignItems: 'center',
951
- fontSize: '12px',
952
- gap: '4px',
953
- }}
954
- >
955
- <span
956
- style={{
957
- display: 'inline-block',
958
- width: '20px',
959
- height: '10px',
960
- border: '1px solid currentColor',
961
- borderRadius: '2px',
962
- position: 'relative',
963
- marginRight: '2px',
964
- }}
965
- >
966
- <span
967
- style={{
968
- position: 'absolute',
969
- left: '1px',
970
- top: '1px',
971
- bottom: '1px',
972
- width: '12px',
973
- backgroundColor: 'currentColor',
974
- borderRadius: '1px',
975
- }}
976
- ></span>
977
- <span
978
- style={{
979
- position: 'absolute',
980
- right: '-4px',
981
- top: '2px',
982
- width: '2px',
983
- height: '6px',
984
- backgroundColor: 'currentColor',
985
- borderRadius: '0 1px 1px 0',
986
- }}
987
- ></span>
988
- </span>
989
- <span>75%</span>
990
- </div>
991
-
992
- {/* WiFi icon */}
993
- <div style={{ fontSize: '14px' }}>📶</div>
994
-
995
- {/* Time */}
996
- <span style={{ fontSize: '13px', fontWeight: 500 }}>
997
- {currentTime || '10:30 AM'}
998
- </span>
999
-
1000
- {/* User profile */}
1001
- <div
1002
- style={{
1003
- position: 'relative',
1004
- width: '26px',
1005
- height: '26px',
1006
- borderRadius: '50%',
1007
- background: 'linear-gradient(135deg, #64B5F6, #1976D2)',
1008
- display: 'flex',
1009
- alignItems: 'center',
1010
- justifyContent: 'center',
1011
- fontSize: '12px',
1012
- fontWeight: 600,
1013
- color: 'white',
1014
- cursor: 'pointer',
1015
- boxShadow: '0 2px 5px rgba(0,0,0,0.2)',
1016
- }}
1017
- >
1018
- A
1019
- {notificationCount > 0 && (
1020
- <span
1021
- style={{
1022
- position: 'absolute',
1023
- top: '-4px',
1024
- right: '-4px',
1025
- width: '14px',
1026
- height: '14px',
1027
- borderRadius: '50%',
1028
- backgroundColor: '#FF3B30',
1029
- color: 'white',
1030
- fontSize: '10px',
1031
- display: 'flex',
1032
- alignItems: 'center',
1033
- justifyContent: 'center',
1034
- border: '1px solid rgba(255,255,255,0.8)',
1035
- }}
1036
- >
1037
- {notificationCount}
1038
- </span>
1039
- )}
1040
- </div>
1041
- </div>
1042
- </div>
1043
- </AtomixGlass>
1044
- {/* Center widget - iOS style with improved design */}
1045
- <AtomixGlass
1046
- displacementScale={15}
1047
- blurAmount={2}
1048
- saturation={150}
1049
- aberrationIntensity={0.1}
1050
- cornerRadius={24}
1051
- mode="shader"
1052
- >
1053
- <div style={{ padding: '30px' }}>
1054
- <h2
1055
- style={{
1056
- marginTop: 0,
1057
- fontSize: '26px',
1058
- fontWeight: 600,
1059
- marginBottom: '24px',
1060
- textAlign: 'center',
1061
- background: 'linear-gradient(135deg, #007AFF, #5AC8FA)',
1062
- WebkitBackgroundClip: 'text',
1063
- WebkitTextFillColor: 'transparent',
1064
- }}
1065
- >
1066
- Welcome to Atomix OS
1067
- </h2>
1068
-
1069
- {/* App grid with improved styling */}
1070
- <div
1071
- style={{
1072
- display: 'grid',
1073
- gridTemplateColumns: 'repeat(3, 1fr)',
1074
- gap: '20px',
1075
- marginBottom: '28px',
1076
- }}
1077
- >
1078
- {appIcons.map(app => (
1079
- <div
1080
- key={app.name}
1081
- style={{
1082
- display: 'flex',
1083
- flexDirection: 'column',
1084
- alignItems: 'center',
1085
- gap: '8px',
1086
- }}
1087
- >
1088
- <div
1089
- style={{
1090
- width: '56px',
1091
- height: '56px',
1092
- borderRadius: '14px',
1093
- background: app.color,
1094
- display: 'flex',
1095
- alignItems: 'center',
1096
- justifyContent: 'center',
1097
- fontSize: '24px',
1098
- boxShadow: '0 4px 10px rgba(0,0,0,0.15)',
1099
- transition: 'transform 0.2s ease, box-shadow 0.2s ease',
1100
- cursor: 'pointer',
1101
- transform: 'translateY(0)',
1102
- // Note: React inline styles don't support pseudo-classes like :hover
1103
- // For hover effects, use CSS classes or onMouseEnter/onMouseLeave handlers
1104
- }}
1105
- >
1106
- {app.symbol}
1107
- </div>
1108
- <span
1109
- style={{
1110
- fontSize: '13px',
1111
- fontWeight: 500,
1112
- opacity: 0.9,
1113
- }}
1114
- >
1115
- {app.name}
1116
- </span>
1117
- </div>
1118
- ))}
1119
- </div>
1120
-
1121
- {/* Notification card with improved design */}
1122
- <AtomixGlass
1123
- displacementScale={12}
1124
- blurAmount={5}
1125
- saturation={130}
1126
- aberrationIntensity={1}
1127
- cornerRadius={16}
1128
- elasticity={0}
1129
- mode="shader"
1130
- >
1131
- <div style={{ padding: '18px', fontSize: '14px' }}>
1132
- <div
1133
- style={{
1134
- display: 'flex',
1135
- alignItems: 'center',
1136
- justifyContent: 'space-between',
1137
- marginBottom: '12px',
1138
- }}
1139
- >
1140
- <div
1141
- style={{
1142
- display: 'flex',
1143
- alignItems: 'center',
1144
- gap: '8px',
1145
- fontWeight: 600,
1146
- }}
1147
- >
1148
- <span style={{ fontSize: '16px' }}>📣</span>
1149
- <span>Notifications</span>
1150
- </div>
1151
- <span
1152
- style={{
1153
- fontSize: '12px',
1154
- padding: '2px 8px',
1155
- borderRadius: '10px',
1156
- background: 'rgba(255,45,85,0.2)',
1157
- color: '#FF2D55',
1158
- fontWeight: 600,
1159
- }}
1160
- >
1161
- {notificationCount} New
1162
- </span>
1163
- </div>
1164
-
1165
- <div
1166
- style={{
1167
- padding: '10px 0',
1168
- borderTop: '1px solid rgba(255,255,255,0.1)',
1169
- display: 'flex',
1170
- alignItems: 'center',
1171
- justifyContent: 'space-between',
1172
- }}
1173
- >
1174
- <div>
1175
- <div style={{ fontWeight: 500, marginBottom: '4px' }}>
1176
- New Atomix Glass Component
1177
- </div>
1178
- <div style={{ fontSize: '12px', opacity: 0.8 }}>
1179
- Experience the next generation of UI effects
1180
- </div>
1181
- </div>
1182
- <div
1183
- style={{
1184
- width: '36px',
1185
- height: '36px',
1186
- borderRadius: '8px',
1187
- background: 'linear-gradient(135deg, #007AFF, #5AC8FA)',
1188
- display: 'flex',
1189
- alignItems: 'center',
1190
- justifyContent: 'center',
1191
- fontSize: '18px',
1192
- }}
1193
- >
1194
-
1195
- </div>
1196
- </div>
1197
- </div>
1198
- </AtomixGlass>
1199
- </div>
1200
- </AtomixGlass>
1201
-
1202
- {/* Bottom dock - macOS style with improved design and hover effects */}
1203
- <AtomixGlass
1204
- displacementScale={15}
1205
- blurAmount={2}
1206
- saturation={140}
1207
- aberrationIntensity={1.2}
1208
- cornerRadius={24}
1209
- mode="polar"
1210
- style={{
1211
- maxWidth: '600px',
1212
- }}
1213
- >
1214
- <div
1215
- style={{
1216
- display: 'flex',
1217
- justifyContent: 'center',
1218
- alignItems: 'center',
1219
- gap: '16px',
1220
- padding: '6px',
1221
- }}
1222
- >
1223
- {dockApps.map((app, index) => (
1224
- <div
1225
- key={index}
1226
- style={{
1227
- width: '48px',
1228
- height: '48px',
1229
- borderRadius: '12px',
1230
- background: app.color,
1231
- display: 'flex',
1232
- alignItems: 'center',
1233
- justifyContent: 'center',
1234
- fontSize: '20px',
1235
- cursor: 'pointer',
1236
- transition: 'all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1)',
1237
- transform:
1238
- hoverDockItem === index
1239
- ? 'translateY(-10px) scale(1.1)'
1240
- : 'translateY(0) scale(1)',
1241
- boxShadow:
1242
- hoverDockItem === index
1243
- ? '0 10px 20px rgba(0,0,0,0.2)'
1244
- : '0 4px 10px rgba(0,0,0,0.1)',
1245
- position: 'relative',
1246
- }}
1247
- onMouseEnter={() => setHoverDockItem(index)}
1248
- onMouseLeave={() => setHoverDockItem(null)}
1249
- >
1250
- {app.symbol}
1251
- {/* App name tooltip on hover */}
1252
- {hoverDockItem === index && (
1253
- <div
1254
- style={{
1255
- position: 'absolute',
1256
- top: '-30px',
1257
- left: '50%',
1258
- transform: 'translateX(-50%)',
1259
- background: 'rgba(0,0,0,0.7)',
1260
- color: 'white',
1261
- padding: '4px 10px',
1262
- borderRadius: '6px',
1263
- fontSize: '12px',
1264
- fontWeight: 500,
1265
- whiteSpace: 'nowrap',
1266
- }}
1267
- >
1268
- {app.name}
1269
- </div>
1270
- )}
1271
- </div>
1272
- ))}
1273
-
1274
- {/* Separator line */}
1275
- <div
1276
- style={{
1277
- width: '1px',
1278
- height: '30px',
1279
- background: 'rgba(255,255,255,0.3)',
1280
- margin: '0 4px',
1281
- }}
1282
- ></div>
1283
-
1284
- {/* Trash icon */}
1285
- <div
1286
- style={{
1287
- width: '48px',
1288
- height: '48px',
1289
- borderRadius: '12px',
1290
- background: 'rgba(255,255,255,0.2)',
1291
- display: 'flex',
1292
- alignItems: 'center',
1293
- justifyContent: 'center',
1294
- fontSize: '20px',
1295
- cursor: 'pointer',
1296
- transition: 'all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1)',
1297
- transform:
1298
- hoverDockItem === 999
1299
- ? 'translateY(-10px) scale(1.1)'
1300
- : 'translateY(0) scale(1)',
1301
- boxShadow:
1302
- hoverDockItem === 999
1303
- ? '0 10px 20px rgba(0,0,0,0.2)'
1304
- : '0 4px 10px rgba(0,0,0,0.1)',
1305
- }}
1306
- onMouseEnter={() => setHoverDockItem(999)}
1307
- onMouseLeave={() => setHoverDockItem(null)}
1308
- >
1309
- 🗑️
1310
- </div>
1311
- </div>
1312
- </AtomixGlass>
1313
- </div>
1314
- </BackgroundWrapper>
1315
- );
1316
- },
1317
- parameters: {
1318
- docs: {
1319
- description: {
1320
- story:
1321
- 'An enhanced Apple-inspired UI example showcasing how to create macOS and iOS-like interfaces using the AtomixGlass component. This example includes a realistic menu bar with status icons, app grid with gradient icons, notification center, and an interactive dock with hover effects - all with the signature Apple frosted glass aesthetic.',
1322
- },
1323
- },
1324
- },
1325
- };
1326
-
1327
- // Hero section example
1328
- export const HeroExample: Story = {
1329
- render: () => (
1330
- <BackgroundWrapper backgroundImage={backgroundImages[0]} height="90vh">
1331
- <div>
1332
- <div
1333
- style={{
1334
- display: 'flex',
1335
- flexDirection: 'column',
1336
- alignItems: 'center',
1337
- textAlign: 'center',
1338
- }}
1339
- >
1340
- <AtomixGlass
1341
- displacementScale={45}
1342
- blurAmount={0.08}
1343
- saturation={170}
1344
- aberrationIntensity={2.5}
1345
- elasticity={0.18}
1346
- cornerRadius={30}
1347
- mode="standard"
1348
- style={{ maxWidth: '800px' }}
1349
- >
1350
- <div style={{ padding: '40px 60px' }}>
1351
- <h1 style={{ marginTop: 0, fontSize: '2.5rem' }}>Modern Glass UI</h1>
1352
- <p style={{ fontSize: '1.2rem', marginBottom: '30px' }}>
1353
- Create stunning interfaces with the AtomixGlass component. Perfect for modern, sleek
1354
- designs that stand out.
1355
- </p>
1356
- <div
1357
- style={{ display: 'flex', gap: '15px', justifyContent: 'center', flexWrap: 'wrap' }}
1358
- >
1359
- <button className="c-btn c-btn--primary">Get Started</button>
1360
- <button className="c-btn c-btn--outline-light">Learn More</button>
1361
- </div>
1362
- </div>
1363
- </AtomixGlass>
1364
- </div>
1365
- </div>
1366
- </BackgroundWrapper>
1367
- ),
1368
- };
1369
-
1370
- export const PerformanceOptimization: Story = {
1371
- parameters: {
1372
- docs: {
1373
- description: {
1374
- story:
1375
- 'This example demonstrates performance optimization techniques for the AtomixGlass component. It shows how different settings affect performance and provides best practices for optimal usage.',
1376
- },
1377
- },
1378
- },
1379
- render: () => (
1380
- <BackgroundWrapper backgroundIndex={3} overlay={true}>
1381
- <div style={{ maxWidth: '1200px', margin: '0 auto', padding: '40px 20px' }}>
1382
- <h2 style={{ color: '#fff', marginBottom: '30px', textAlign: 'center' }}>
1383
- Performance Optimization Guide
1384
- </h2>
1385
-
1386
- <div
1387
- style={{
1388
- marginBottom: '40px',
1389
- backgroundColor: 'rgba(0,0,0,0.7)',
1390
- padding: '20px',
1391
- borderRadius: '10px',
1392
- }}
1393
- >
1394
- <h3 style={{ color: '#fff', marginBottom: '15px' }}>Best Practices</h3>
1395
- <ul style={{ color: '#fff', lineHeight: '1.6' }}>
1396
- <li>
1397
- <strong>Limit the number of instances</strong> - Use AtomixGlass components sparingly
1398
- on a single page
1399
- </li>
1400
- <li>
1401
- <strong>Optimize size</strong> - Smaller glass components perform better than
1402
- full-screen ones
1403
- </li>
1404
- <li>
1405
- <strong>Reduce complexity for mobile</strong> - Use simpler settings on mobile devices
1406
- </li>
1407
- <li>
1408
- <strong>Disable effects when not needed</strong> - Turn off hover effects for
1409
- non-interactive elements
1410
- </li>
1411
- <li>
1412
- <strong>Use appropriate mode</strong> - Choose the right mode based on performance
1413
- requirements
1414
- </li>
1415
- </ul>
1416
- </div>
1417
-
1418
- <div className="o-grid">
1419
- <div className="o-grid__row">
1420
- <div className="o-grid__col o-grid__col--12 o-grid__col--6@md">
1421
- <h3 style={{ color: '#fff', marginBottom: '15px' }}>
1422
- High Performance Configuration
1423
- </h3>
1424
- <AtomixGlass
1425
- displacementScale={25}
1426
- blurAmount={0.02}
1427
- saturation={120}
1428
- aberrationIntensity={0.8}
1429
- elasticity={0.1}
1430
- cornerRadius={10}
1431
- mode="standard"
1432
- reducedMotion={false}
1433
- disableEffects={false}
1434
- style={{ height: '100%', minHeight: '200px' }}
1435
- >
1436
- <div style={{ padding: '20px' }}>
1437
- <h4 style={{ marginTop: 0 }}>Optimized for Performance</h4>
1438
- <p>This configuration prioritizes performance over visual effects:</p>
1439
- <ul>
1440
- <li>Low displacement scale (25)</li>
1441
- <li>Minimal blur amount (0.02)</li>
1442
- <li>Reduced saturation (120%)</li>
1443
- <li>Simple mode with no hover effects</li>
1444
- <li>No border effects</li>
1445
- </ul>
1446
- <p>
1447
- <strong>Best for:</strong> Mobile devices, pages with multiple instances, or
1448
- low-end hardware
1449
- </p>
1450
- </div>
1451
- </AtomixGlass>
1452
- </div>
1453
-
1454
- <div className="o-grid__col o-grid__col--12 o-grid__col--6@md">
1455
- <h3 style={{ color: '#fff', marginBottom: '15px' }}>Balanced Configuration</h3>
1456
- <AtomixGlass
1457
- displacementScale={55}
1458
- blurAmount={0.04}
1459
- saturation={150}
1460
- aberrationIntensity={1.8}
1461
- elasticity={0.15}
1462
- cornerRadius={15}
1463
- mode="standard"
1464
- enablePerformanceMonitoring={true}
1465
- style={{ height: '100%', minHeight: '200px' }}
1466
- >
1467
- <div style={{ padding: '20px' }}>
1468
- <h4 style={{ marginTop: 0 }}>Balanced Approach</h4>
1469
- <p>This configuration balances performance and visual appeal:</p>
1470
- <ul>
1471
- <li>Moderate displacement scale (55)</li>
1472
- <li>Medium blur amount (0.04)</li>
1473
- <li>Balanced saturation (150%)</li>
1474
- <li>Normal mode with subtle hover effects</li>
1475
- <li>Minimal border effects</li>
1476
- </ul>
1477
- <p>
1478
- <strong>Best for:</strong> Most desktop applications and modern devices
1479
- </p>
1480
- </div>
1481
- </AtomixGlass>
1482
- </div>
1483
- </div>
1484
-
1485
- <div className="o-grid__row" style={{ marginTop: '30px' }}>
1486
- <div className="o-grid__col o-grid__col--12">
1487
- <div
1488
- style={{
1489
- backgroundColor: 'rgba(0,0,0,0.7)',
1490
- padding: '20px',
1491
- borderRadius: '10px',
1492
- }}
1493
- >
1494
- <h3 style={{ color: '#fff', marginBottom: '15px' }}>Performance Monitoring Tips</h3>
1495
- <ol style={{ color: '#fff', lineHeight: '1.6' }}>
1496
- <li>Use browser developer tools to monitor performance</li>
1497
- <li>Check for dropped frames in the Performance panel</li>
1498
- <li>Monitor GPU usage when using advanced effects</li>
1499
- <li>Test on various devices to ensure consistent performance</li>
1500
- <li>
1501
- Consider using the <code>React.memo</code> HOC to prevent unnecessary re-renders
1502
- </li>
1503
- </ol>
1504
-
1505
- <div
1506
- style={{
1507
- marginTop: '20px',
1508
- padding: '15px',
1509
- backgroundColor: 'rgba(255,255,255,0.1)',
1510
- borderRadius: '5px',
1511
- }}
1512
- >
1513
- <h4 style={{ color: '#fff', marginBottom: '10px' }}>
1514
- Code Example: Optimized Usage
1515
- </h4>
1516
- <pre
1517
- style={{
1518
- backgroundColor: 'rgba(0,0,0,0.5)',
1519
- padding: '15px',
1520
- borderRadius: '5px',
1521
- overflow: 'auto',
1522
- }}
1523
- >
1524
- <code style={{ color: '#e6e6e6', display: 'block', fontFamily: 'monospace' }}>
1525
- {`import React, { memo } from 'react';
1526
- import AtomixGlass from './AtomixGlass';
1527
-
1528
- // Use memo to prevent unnecessary re-renders
1529
- const OptimizedGlassCard = memo(({ title, content }) => {
1530
- // Adjust settings based on device capability
1531
- const isMobile = window.innerWidth < 768;
1532
-
1533
- return (
1534
- <AtomixGlass
1535
- displacementScale={isMobile ? 10 : 20}
1536
- blurAmount={isMobile ? 5 : 10}
1537
- saturation={isMobile ? 120 : 150}
1538
- aberrationIntensity={isMobile ? 0.5 : 1.5}
1539
- mode={isMobile ? "simple" : "normal"}
1540
- showHoverEffects={!isMobile}
1541
- >
1542
- <div style={{ padding: '20px' }}>
1543
- <h3>{title}</h3>
1544
- <p>{content}</p>
1545
- </div>
1546
- </AtomixGlass>
1547
- );
1548
- });
1549
-
1550
- export default OptimizedGlassCard;`}
1551
- </code>
1552
- </pre>
1553
- </div>
1554
- </div>
1555
- </div>
1556
- </div>
1557
- </div>
1558
- </div>
1559
- </BackgroundWrapper>
1560
- ),
1561
- };
1562
-
1563
- /**
1564
- * Interactive Playground story with dynamic controls for all component props
1565
- *
1566
- * This story provides a comprehensive playground for experimenting with all
1567
- * AtomixGlass component properties in real-time.
1568
- */
1569
- export const InteractivePlayground: Story = {
1570
- render: () => {
1571
- // eslint-disable-next-line react-hooks/rules-of-hooks
1572
- const [settings, setSettings] = useState({
1573
- displacementScale: 70,
1574
- blurAmount: 1,
1575
- saturation: 140,
1576
- aberrationIntensity: 2,
1577
- cornerRadius: 20,
1578
- mode: 'standard' as const,
1579
- showBorderEffects: true,
1580
- showHoverEffects: true,
1581
- overLight: false,
1582
- background: backgrounds.blueGradient,
1583
- useVideoBackground: false,
1584
- elasticity: 0.15,
1585
- });
1586
-
1587
- const handleChange = (property: string, value: any) => {
1588
- setSettings(prev => ({
1589
- ...prev,
1590
- [property]: value,
1591
- }));
1592
- };
1593
-
1594
- const modes = ['standard', 'polar', 'prominent', 'shader'] as const;
1595
- const backgroundOptions = Object.entries(backgrounds).map(([key, value]) => ({
1596
- label: key,
1597
- value,
1598
- }));
1599
-
1600
- // Control panel styles
1601
- const controlPanelStyle = {
1602
- width: '400px',
1603
- padding: '20px',
1604
- borderRadius: '12px',
1605
- background: 'rgba(0,0,0,0.7)',
1606
- boxShadow: '0 4px 20px rgba(0,0,0,0.3)',
1607
- color: 'white',
1608
- fontSize: '14px',
1609
- };
1610
-
1611
- const sliderContainerStyle = {
1612
- marginBottom: '16px',
1613
- };
1614
-
1615
- const sliderLabelStyle = {
1616
- display: 'flex',
1617
- justifyContent: 'space-between',
1618
- marginBottom: '6px',
1619
- };
1620
-
1621
- const sliderStyle = {
1622
- width: '100%',
1623
- accentColor: '#6366f1',
1624
- };
1625
-
1626
- const selectStyle = {
1627
- width: '100%',
1628
- padding: '8px',
1629
- backgroundColor: 'rgba(255,255,255,0.1)',
1630
- color: 'white',
1631
- border: '1px solid rgba(255,255,255,0.2)',
1632
- borderRadius: '4px',
1633
- marginBottom: '16px',
1634
- };
1635
-
1636
- const checkboxContainerStyle = {
1637
- display: 'flex',
1638
- alignItems: 'center',
1639
- marginBottom: '12px',
1640
- gap: '8px',
1641
- };
1642
-
1643
- return (
1644
- <BackgroundWrapper
1645
- backgroundImage={settings.useVideoBackground ? 'transparent' : settings.background}
1646
- height="80vh"
1647
- style={{ maxWidth: '1400px', position: 'relative', overflow: 'hidden' }}
1648
- >
1649
- {/* Control Panel */}
1650
- <div style={controlPanelStyle}>
1651
- <h3 style={{ margin: '0 0 16px 0', fontSize: '18px', textAlign: 'center' }}>
1652
- AtomixGlass Controls
1653
- </h3>
1654
-
1655
- {/* Displacement Scale */}
1656
- <div style={sliderContainerStyle}>
1657
- <div style={sliderLabelStyle}>
1658
- <label htmlFor="displacementScale">Displacement Scale</label>
1659
- <span>{settings.displacementScale}</span>
1660
- </div>
1661
- <input
1662
- type="range"
1663
- id="displacementScale"
1664
- min="0"
1665
- max="100"
1666
- value={settings.displacementScale}
1667
- onChange={e => handleChange('displacementScale', parseInt(e.target.value))}
1668
- style={sliderStyle}
1669
- />
1670
- </div>
1671
-
1672
- {/* Blur Amount */}
1673
- <div style={sliderContainerStyle}>
1674
- <div style={sliderLabelStyle}>
1675
- <label htmlFor="blurAmount">Blur Amount</label>
1676
- <span>{settings.blurAmount}</span>
1677
- </div>
1678
- <input
1679
- type="range"
1680
- id="blurAmount"
1681
- min="0"
1682
- max="20"
1683
- step="0.05"
1684
- value={settings.blurAmount}
1685
- onChange={e => handleChange('blurAmount', parseFloat(e.target.value))}
1686
- style={sliderStyle}
1687
- />
1688
- </div>
1689
-
1690
- {/* Saturation */}
1691
- <div style={sliderContainerStyle}>
1692
- <div style={sliderLabelStyle}>
1693
- <label htmlFor="saturation">Saturation</label>
1694
- <span>{settings.saturation}%</span>
1695
- </div>
1696
- <input
1697
- type="range"
1698
- id="saturation"
1699
- min="0"
1700
- max="300"
1701
- value={settings.saturation}
1702
- onChange={e => handleChange('saturation', parseInt(e.target.value))}
1703
- style={sliderStyle}
1704
- />
1705
- </div>
1706
-
1707
- {/* Aberration Intensity */}
1708
- <div style={sliderContainerStyle}>
1709
- <div style={sliderLabelStyle}>
1710
- <label htmlFor="aberrationIntensity">Aberration Intensity</label>
1711
- <span>{settings.aberrationIntensity}</span>
1712
- </div>
1713
- <input
1714
- type="range"
1715
- id="aberrationIntensity"
1716
- min="0"
1717
- max="10"
1718
- step="0.1"
1719
- value={settings.aberrationIntensity}
1720
- onChange={e => handleChange('aberrationIntensity', parseFloat(e.target.value))}
1721
- style={sliderStyle}
1722
- />
1723
- </div>
1724
-
1725
- {/* Corner Radius */}
1726
- <div style={sliderContainerStyle}>
1727
- <div style={sliderLabelStyle}>
1728
- <label htmlFor="cornerRadius">Corner Radius</label>
1729
- <span>{settings.cornerRadius}px</span>
1730
- </div>
1731
- <input
1732
- type="range"
1733
- id="cornerRadius"
1734
- min="0"
1735
- max="50"
1736
- value={settings.cornerRadius}
1737
- onChange={e => handleChange('cornerRadius', parseInt(e.target.value))}
1738
- style={sliderStyle}
1739
- />
1740
- </div>
1741
-
1742
- {/* Elasticity */}
1743
- <div style={sliderContainerStyle}>
1744
- <div style={sliderLabelStyle}>
1745
- <label htmlFor="elasticity">Elasticity</label>
1746
- <span>{settings.elasticity}</span>
1747
- </div>
1748
- <input
1749
- type="range"
1750
- id="elasticity"
1751
- min="0"
1752
- max="1"
1753
- step="0.01"
1754
- value={settings.elasticity}
1755
- onChange={e => handleChange('elasticity',e.target.value)}
1756
- style={sliderStyle}
1757
- />
1758
- </div>
1759
-
1760
- {/* Mode Select */}
1761
- <label htmlFor="mode" style={{ display: 'block', marginBottom: '6px' }}>
1762
- Mode
1763
- </label>
1764
- <select
1765
- id="mode"
1766
- value={settings.mode}
1767
- onChange={e => handleChange('mode', e.target.value)}
1768
- style={selectStyle}
1769
- >
1770
- {modes.map(mode => (
1771
- <option key={mode} value={mode}>
1772
- {mode.charAt(0).toUpperCase() + mode.slice(1)}
1773
- </option>
1774
- ))}
1775
- </select>
1776
-
1777
- {/* Background Select */}
1778
- <label htmlFor="background" style={{ display: 'block', marginBottom: '6px' }}>
1779
- Background
1780
- </label>
1781
- <select
1782
- id="background"
1783
- value={settings.background}
1784
- onChange={e => handleChange('background', e.target.value)}
1785
- style={selectStyle}
1786
- >
1787
- {backgroundOptions.map(option => (
1788
- <option key={option.label} value={option.value}>
1789
- {option.label}
1790
- </option>
1791
- ))}
1792
- </select>
1793
-
1794
- {/* Checkboxes */}
1795
- <div style={checkboxContainerStyle}>
1796
- <input
1797
- type="checkbox"
1798
- id="showBorderEffects"
1799
- checked={settings.showBorderEffects}
1800
- onChange={e => handleChange('showBorderEffects', e.target.checked)}
1801
- />
1802
- <label htmlFor="showBorderEffects">Show Border Effects</label>
1803
- </div>
1804
-
1805
- <div style={checkboxContainerStyle}>
1806
- <input
1807
- type="checkbox"
1808
- id="showHoverEffects"
1809
- checked={settings.showHoverEffects}
1810
- onChange={e => handleChange('showHoverEffects', e.target.checked)}
1811
- />
1812
- <label htmlFor="showHoverEffects">Show Hover Effects</label>
1813
- </div>
1814
-
1815
- <div style={checkboxContainerStyle}>
1816
- <input
1817
- type="checkbox"
1818
- id="overLight"
1819
- checked={settings.overLight}
1820
- onChange={e => handleChange('overLight', e.target.checked)}
1821
- />
1822
- <label htmlFor="overLight">Over Light</label>
1823
- </div>
1824
-
1825
- <div style={checkboxContainerStyle}>
1826
- <input
1827
- type="checkbox"
1828
- id="useVideoBackground"
1829
- checked={settings.useVideoBackground}
1830
- onChange={e => handleChange('useVideoBackground', e.target.checked)}
1831
- />
1832
- <label htmlFor="useVideoBackground">Use Video Background</label>
1833
- </div>
1834
- </div>
1835
-
1836
- {/* Video Background */}
1837
- {settings.useVideoBackground && (
1838
- <video
1839
- autoPlay
1840
- loop
1841
- muted
1842
- playsInline
1843
- style={{
1844
- position: 'absolute',
1845
- top: 0,
1846
- left: 0,
1847
- width: '100%',
1848
- height: '100%',
1849
- objectFit: 'cover',
1850
- zIndex: -1,
1851
- }}
1852
- >
1853
- <source src={backgrounds.videoBackground} type="video/mp4" />
1854
- </video>
1855
- )}
1856
-
1857
- {/* Glass Component Preview */}
1858
- <div
1859
- style={{
1860
- display: 'flex',
1861
- justifyContent: 'center',
1862
- alignItems: 'center',
1863
- height: '100%',
1864
- width: '100%',
1865
- paddingLeft: '300px', // Make room for the control panel
1866
- }}
1867
- >
1868
- <AtomixGlass
1869
- displacementScale={settings.displacementScale}
1870
- blurAmount={settings.blurAmount}
1871
- saturation={settings.saturation}
1872
- aberrationIntensity={settings.aberrationIntensity}
1873
- cornerRadius={settings.cornerRadius}
1874
- mode={settings.mode}
1875
- overLight={settings.overLight}
1876
- elasticity={settings.elasticity}
1877
- style={{ width: '400px', maxWidth: '100%' }}
1878
- >
1879
- <div style={{ padding: '30px', textAlign: 'center' }}>
1880
- <h2 style={{ marginTop: 0, fontSize: '24px', fontWeight: 500, marginBottom: '16px' }}>
1881
- Interactive Preview
1882
- </h2>
1883
- <p style={{ fontSize: '16px', lineHeight: 1.6, marginBottom: '20px' }}>
1884
- Adjust the controls on the left to see how different properties affect the glass
1885
- effect in real-time.
1886
- {settings.useVideoBackground &&
1887
- ' Try the video background for an enhanced experience!'}
1888
- </p>
1889
- <div
1890
- style={{
1891
- display: 'flex',
1892
- justifyContent: 'center',
1893
- gap: '12px',
1894
- flexWrap: 'wrap',
1895
- }}
1896
- >
1897
- <Button label="Primary" variant="primary" glass={{elasticity: 0}}/>
1898
- <Button label="secondary" variant="secondary" glass={{elasticity: 0}}/>
1899
- </div>
1900
- </div>
1901
- </AtomixGlass>
1902
- </div>
1903
- </BackgroundWrapper>
1904
- );
1905
- },
1906
- parameters: {
1907
- docs: {
1908
- description: {
1909
- story:
1910
- 'An interactive playground that allows you to experiment with all AtomixGlass component properties in real-time. Use the control panel to adjust settings and see how they affect the appearance and behavior of the glass effect. Toggle the video background option to see how the glass effect works with dynamic content.',
1911
- },
1912
- },
1913
- },
1914
- };
1915
-
1916
- // Accessibility example
1917
- /**
1918
- * Accessible Example - Demonstrates accessibility best practices
1919
- *
1920
- * This story showcases how to implement accessibility features with AtomixGlass
1921
- * components, ensuring they are usable by people with disabilities.
1922
- */
1923
- export const AccessibleExample: Story = {
1924
- render: () => (
1925
- <BackgroundWrapper
1926
- backgroundImage={backgrounds.abstract2}
1927
- height="70vh"
1928
- width="90vw"
1929
- overlayOpacity={0.1}
1930
- aria-hidden="false"
1931
- >
1932
- <AtomixGlass
1933
- displacementScale={40}
1934
- blurAmount={1}
1935
- saturation={160}
1936
- aberrationIntensity={1.5}
1937
- elasticity={0}
1938
- cornerRadius={15}
1939
- aria-label="Contact form container"
1940
- aria-describedby="form-description"
1941
- role="region"
1942
- tabIndex={-1}
1943
- reducedMotion={false}
1944
- highContrast={false}
1945
- style={{
1946
- width: '400px',
1947
- cursor: 'default',
1948
- }}
1949
- >
1950
- <div style={{ padding: '30px' }}>
1951
- <h2
1952
- id="form-title"
1953
- style={{
1954
- marginTop: 0,
1955
- fontSize: '24px',
1956
- marginBottom: '20px',
1957
- color: '#ffffff',
1958
- }}
1959
- >
1960
- Contact Us
1961
- </h2>
1962
- width: '80%',
1963
- {/* Adding description for screen readers */}
1964
- <p id="form-description" style={{ marginBottom: '20px', fontSize: '16px' }}>
1965
- Please fill out the form below to get in touch with our team.
1966
- </p>
1967
- <form aria-describedby="form-description">
1968
- <div style={{ marginBottom: '20px' }}>
1969
- <label
1970
- htmlFor="name"
1971
- style={{
1972
- display: 'block',
1973
- marginBottom: '8px',
1974
- fontWeight: 500,
1975
- }}
1976
- >
1977
- Name{' '}
1978
- <span aria-hidden="true" style={{ color: '#ff3b30' }}>
1979
- *
1980
- </span>
1981
- </label>
1982
- <input
1983
- id="name"
1984
- type="text"
1985
- aria-required="true"
1986
- aria-invalid="false"
1987
- aria-describedby="name-error"
1988
- style={{
1989
- width: '100%',
1990
- padding: '10px',
1991
- borderRadius: '6px',
1992
- border: '1px solid rgba(255, 255, 255, 0.3)',
1993
- background: 'rgba(255, 255, 255, 0.1)',
1994
- color: '#ffffff',
1995
- fontSize: '16px',
1996
- }}
1997
- />
1998
- <div
1999
- id="name-error"
2000
- role="alert"
2001
- style={{
2002
- height: '20px',
2003
- fontSize: '14px',
2004
- color: '#ff3b30',
2005
- marginTop: '4px',
2006
- }}
2007
- ></div>
2008
- </div>
2009
-
2010
- <div style={{ marginBottom: '20px' }}>
2011
- <label
2012
- htmlFor="email"
2013
- style={{
2014
- display: 'block',
2015
- marginBottom: '8px',
2016
- fontWeight: 500,
2017
- }}
2018
- >
2019
- Email{' '}
2020
- <span aria-hidden="true" style={{ color: '#ff3b30' }}>
2021
- *
2022
- </span>
2023
- </label>
2024
- <input
2025
- id="email"
2026
- type="email"
2027
- aria-required="true"
2028
- aria-invalid="false"
2029
- aria-describedby="email-error"
2030
- style={{
2031
- width: '100%',
2032
- padding: '10px',
2033
- borderRadius: '6px',
2034
- border: '1px solid rgba(255, 255, 255, 0.3)',
2035
- background: 'rgba(255, 255, 255, 0.1)',
2036
- color: '#ffffff',
2037
- fontSize: '16px',
2038
- }}
2039
- />
2040
- <div
2041
- id="email-error"
2042
- role="alert"
2043
- style={{
2044
- height: '20px',
2045
- fontSize: '14px',
2046
- color: '#ff3b30',
2047
- marginTop: '4px',
2048
- }}
2049
- ></div>
2050
- </div>
2051
-
2052
- <div style={{ marginBottom: '20px' }}>
2053
- <label
2054
- htmlFor="message"
2055
- style={{
2056
- display: 'block',
2057
- marginBottom: '8px',
2058
- fontWeight: 500,
2059
- }}
2060
- >
2061
- Message{' '}
2062
- <span aria-hidden="true" style={{ color: '#ff3b30' }}>
2063
- *
2064
- </span>
2065
- </label>
2066
- <textarea
2067
- id="message"
2068
- rows={4}
2069
- aria-required="true"
2070
- aria-invalid="false"
2071
- aria-describedby="message-error"
2072
- style={{
2073
- width: '100%',
2074
- padding: '10px',
2075
- borderRadius: '6px',
2076
- border: '1px solid rgba(255, 255, 255, 0.3)',
2077
- background: 'rgba(255, 255, 255, 0.1)',
2078
- color: '#ffffff',
2079
- fontSize: '16px',
2080
- resize: 'vertical',
2081
- }}
2082
- />
2083
- <div
2084
- id="message-error"
2085
- role="alert"
2086
- style={{
2087
- height: '20px',
2088
- fontSize: '14px',
2089
- color: '#ff3b30',
2090
- marginTop: '4px',
2091
- }}
2092
- ></div>
2093
- </div>
2094
-
2095
- <div style={{ marginBottom: '20px' }}>
2096
- <div style={{ display: 'flex', alignItems: 'center' }}>
2097
- <input
2098
- id="privacy-policy"
2099
- type="checkbox"
2100
- aria-required="true"
2101
- style={{
2102
- marginRight: '10px',
2103
- width: '18px',
2104
- height: '18px',
2105
- }}
2106
- />
2107
- <label htmlFor="privacy-policy">
2108
- I agree to the{' '}
2109
- <a href="#" style={{ color: '#ffffff', textDecoration: 'underline' }}>
2110
- Privacy Policy
2111
- </a>
2112
- </label>
2113
- </div>
2114
- </div>
2115
-
2116
- <button type="submit" className="c-btn c-btn--primary" aria-label="Submit contact form">
2117
- Send Message
2118
- </button>
2119
- </form>
2120
- </div>
2121
- </AtomixGlass>
2122
- </BackgroundWrapper>
2123
- ),
2124
- parameters: {
2125
- docs: {
2126
- description: {
2127
- story:
2128
- 'An example showcasing accessibility features with the AtomixGlass component. This form includes proper ARIA attributes, semantic HTML, and keyboard navigation support.',
2129
- },
2130
- },
2131
- },
2132
- };
2133
-
2134
- /**
2135
- * Mobile UI Example - Showcases the component on smaller screens
2136
- *
2137
- * This story demonstrates how AtomixGlass components can be used to create
2138
- * mobile-friendly interfaces with responsive design and touch interactions.
2139
- */
2140
- export const MobileUIExample: Story = {
2141
- render: () => {
2142
- // eslint-disable-next-line react-hooks/rules-of-hooks
2143
- const [activeTab, setActiveTab] = useState('home');
2144
- // eslint-disable-next-line react-hooks/rules-of-hooks
2145
- const [notificationCount, setNotificationCount] = useState(3);
2146
-
2147
- const handleTabChange = (tab: string) => {
2148
- setActiveTab(tab);
2149
- };
2150
-
2151
- const clearNotifications = () => {
2152
- setNotificationCount(0);
2153
- };
2154
-
2155
- // Mobile device frame styles
2156
- const phoneFrameStyle = {
2157
- width: '375px',
2158
- height: '667px',
2159
- borderRadius: '36px',
2160
- padding: '12px',
2161
- boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.5)',
2162
- position: 'relative' as const,
2163
- };
2164
-
2165
- const phoneScreenStyle = {
2166
- width: '100%',
2167
- height: '100%',
2168
- borderRadius: '24px',
2169
- position: 'relative' as const,
2170
- backgroundImage:
2171
- 'url(https://images.unsplash.com/photo-1697231924875-a6eea91b071b?q=80&w=987&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)',
2172
- backgroundSize: 'cover' as const,
2173
- backgroundPosition: 'center' as const,
2174
- overflow: 'hidden',
2175
- color: 'white',
2176
- };
2177
-
2178
- const phoneNotchStyle = {
2179
- position: 'absolute' as const,
2180
- top: '0',
2181
- left: '50%',
2182
- transform: 'translateX(-50%)',
2183
- width: '180px',
2184
- height: '30px',
2185
- borderBottomLeftRadius: '14px',
2186
- borderBottomRightRadius: '14px',
2187
- background: '#000',
2188
- zIndex: 10,
2189
- };
2190
-
2191
- // App content styles
2192
- const appContentStyle = {
2193
- height: '100%',
2194
- display: 'flex',
2195
- flexDirection: 'column' as const,
2196
- position: 'relative' as const,
2197
- };
2198
-
2199
- const headerStyle = {
2200
- padding: '50px 20px 15px',
2201
- display: 'flex',
2202
- width: '100%',
2203
- justifyContent: 'space-between',
2204
- alignItems: 'center',
2205
- };
2206
-
2207
- const mainContentStyle = {
2208
- flex: 1,
2209
- padding: '0 15px',
2210
- };
2211
-
2212
- // Tab content based on active tab
2213
- const renderTabContent = () => {
2214
- switch (activeTab) {
2215
- case 'home':
2216
- return (
2217
- <div style={{ padding: '10px 0' }}>
2218
- <AtomixGlass
2219
- displacementScale={35}
2220
- blurAmount={1}
2221
- saturation={150}
2222
- aberrationIntensity={1.5}
2223
- elasticity={0.2}
2224
- cornerRadius={20}
2225
- mode="standard"
2226
- >
2227
- <div style={{ padding: '20px' }}>
2228
- <h3 style={{ margin: '0 0 10px 0', fontSize: '18px', color: 'white' }}>
2229
- Welcome Back
2230
- </h3>
2231
- <p
2232
- style={{
2233
- margin: '0 0 15px 0',
2234
- fontSize: '14px',
2235
- lineHeight: 1.5,
2236
- color: 'white',
2237
- }}
2238
- >
2239
- Your daily summary and activity feed
2240
- </p>
2241
- <div
2242
- style={{
2243
- display: 'flex',
2244
- alignItems: 'center',
2245
- gap: '10px',
2246
- marginTop: '15px',
2247
- }}
2248
- >
2249
- <div
2250
- style={{
2251
- width: '40px',
2252
- height: '40px',
2253
- borderRadius: '50%',
2254
- background: 'rgba(255,255,255,0.2)',
2255
- display: 'flex',
2256
- alignItems: 'center',
2257
- justifyContent: 'center',
2258
- fontSize: '18px',
2259
- }}
2260
- >
2261
- 👤
2262
- </div>
2263
- <div>
2264
- <div style={{ fontWeight: 500, color: 'white' }}>User Profile</div>
2265
- <div style={{ fontSize: '12px', opacity: 0.7, color: 'white' }}>
2266
- View your account
2267
- </div>
2268
- </div>
2269
- </div>
2270
- </div>
2271
- </AtomixGlass>
2272
-
2273
- <div style={{ height: '15px' }} />
2274
-
2275
- <AtomixGlass
2276
- displacementScale={30}
2277
- blurAmount={2}
2278
- saturation={165}
2279
- aberrationIntensity={0}
2280
- elasticity={0.2}
2281
- cornerRadius={15}
2282
- mode="standard"
2283
- >
2284
- <div style={{ padding: '20px' }}>
2285
- <h3 style={{ margin: '0 0 15px 0', fontSize: '16px', color: 'white' }}>
2286
- Recent Activity
2287
- </h3>
2288
- {[1, 2, 3].map(item => (
2289
- <div
2290
- key={item}
2291
- style={{
2292
- padding: '10px 0',
2293
- borderBottom: item < 3 ? '1px solid rgba(255,255,255,0.1)' : 'none',
2294
- display: 'flex',
2295
- alignItems: 'center',
2296
- gap: '10px',
2297
- }}
2298
- >
2299
- <div
2300
- style={{
2301
- width: '32px',
2302
- height: '32px',
2303
- borderRadius: '8px',
2304
- background: 'rgba(255,255,255,0.15)',
2305
- display: 'flex',
2306
- alignItems: 'center',
2307
- justifyContent: 'center',
2308
- fontSize: '14px',
2309
- color: 'white',
2310
- }}
2311
- >
2312
- {item === 1 ? '📝' : item === 2 ? '🔔' : '💬'}
2313
- </div>
2314
- <div>
2315
- <div style={{ fontSize: '14px', color: 'white' }}>
2316
- {item === 1
2317
- ? 'New document created'
2318
- : item === 2
2319
- ? 'Reminder: Meeting at 3 PM'
2320
- : 'New message from Sarah'}
2321
- </div>
2322
- <div style={{ fontSize: '12px', opacity: 0.7, color: 'white' }}>
2323
- {item === 1 ? '5 minutes ago' : item === 2 ? '1 hour ago' : '3 hours ago'}
2324
- </div>
2325
- </div>
2326
- </div>
2327
- ))}
2328
- </div>
2329
- </AtomixGlass>
2330
- </div>
2331
- );
2332
- case 'search':
2333
- return (
2334
- <div style={{ padding: '10px 0' }}>
2335
- <AtomixGlass
2336
- displacementScale={40}
2337
- blurAmount={1}
2338
- saturation={155}
2339
- aberrationIntensity={1.8}
2340
- elasticity={0.13}
2341
- cornerRadius={15}
2342
- mode="standard"
2343
- >
2344
- <div style={{ padding: '15px' }}>
2345
- <div
2346
- style={{
2347
- display: 'flex',
2348
- alignItems: 'center',
2349
- gap: '10px',
2350
- background: 'rgba(255,255,255,0.1)',
2351
- borderRadius: '10px',
2352
- padding: '8px 12px',
2353
- }}
2354
- >
2355
- <span>🔍</span>
2356
- <input
2357
- type="text"
2358
- placeholder="Search..."
2359
- style={{
2360
- background: 'transparent',
2361
- border: 'none',
2362
- outline: 'none',
2363
- color: 'white',
2364
- width: '100%',
2365
- fontSize: '14px',
2366
- }}
2367
- />
2368
- </div>
2369
- </div>
2370
- </AtomixGlass>
2371
-
2372
- <div style={{ height: '15px' }} />
2373
-
2374
- <AtomixGlass
2375
- displacementScale={15}
2376
- blurAmount={1}
2377
- saturation={140}
2378
- aberrationIntensity={1}
2379
- cornerRadius={15}
2380
- >
2381
- <div style={{ padding: '20px' }}>
2382
- <h3 style={{ margin: '0 0 15px 0', fontSize: '16px', color: '#fff' }}>
2383
- Search Categories
2384
- </h3>
2385
- <div
2386
- style={{
2387
- display: 'grid',
2388
- gridTemplateColumns: 'repeat(2, 1fr)',
2389
- gap: '10px',
2390
- }}
2391
- >
2392
- {['Photos', 'Documents', 'Messages', 'Settings'].map(category => (
2393
- <div
2394
- key={category}
2395
- style={{
2396
- padding: '15px',
2397
- background: 'rgba(255,255,255,0.1)',
2398
- borderRadius: '10px',
2399
- textAlign: 'center',
2400
- fontSize: '14px',
2401
- }}
2402
- >
2403
- {category}
2404
- </div>
2405
- ))}
2406
- </div>
2407
- </div>
2408
- </AtomixGlass>
2409
- </div>
2410
- );
2411
- case 'notifications':
2412
- return (
2413
- <div style={{ padding: '10px 0' }}>
2414
- <AtomixGlass
2415
- displacementScale={50}
2416
- blurAmount={1}
2417
- saturation={175}
2418
- aberrationIntensity={2.2}
2419
- elasticity={0.14}
2420
- cornerRadius={15}
2421
- mode="standard"
2422
- >
2423
- <div style={{ padding: '20px' }}>
2424
- <div
2425
- style={{
2426
- display: 'flex',
2427
- justifyContent: 'space-between',
2428
- alignItems: 'center',
2429
- marginBottom: '15px',
2430
- }}
2431
- >
2432
- <h3 style={{ margin: 0, fontSize: '18px', color: 'white' }}>Notifications</h3>
2433
- <button
2434
- onClick={clearNotifications}
2435
- style={{
2436
- background: 'rgba(255,255,255,0.2)',
2437
- border: 'none',
2438
- borderRadius: '5px',
2439
- padding: '5px 10px',
2440
- fontSize: '12px',
2441
- color: 'white',
2442
- cursor: 'pointer',
2443
- }}
2444
- >
2445
- Clear All
2446
- </button>
2447
- </div>
2448
-
2449
- {notificationCount > 0 ? (
2450
- Array.from({ length: notificationCount }).map((_, index) => (
2451
- <div
2452
- key={index}
2453
- style={{
2454
- padding: '12px',
2455
- background: 'rgba(255,255,255,0.1)',
2456
- borderRadius: '10px',
2457
- marginBottom: '10px',
2458
- }}
2459
- >
2460
- <div
2461
- style={{
2462
- display: 'flex',
2463
- alignItems: 'center',
2464
- gap: '10px',
2465
- }}
2466
- >
2467
- <div
2468
- style={{
2469
- width: '36px',
2470
- height: '36px',
2471
- borderRadius: '50%',
2472
- background: 'rgba(255,255,255,0.2)',
2473
- display: 'flex',
2474
- alignItems: 'center',
2475
- justifyContent: 'center',
2476
- fontSize: '16px',
2477
- }}
2478
- >
2479
- {index === 0 ? '📱' : index === 1 ? '🔔' : '✉️'}
2480
- </div>
2481
- <div>
2482
- <div style={{ fontSize: '14px', fontWeight: 500, color: 'white' }}>
2483
- {index === 0
2484
- ? 'New Login Detected'
2485
- : index === 1
2486
- ? 'Calendar Reminder'
2487
- : 'New Message'}
2488
- </div>
2489
- <div style={{ fontSize: '12px', opacity: 0.7, color: 'white' }}>
2490
- {index === 0
2491
- ? 'A new device logged into your account'
2492
- : index === 1
2493
- ? 'Meeting with design team in 30 minutes'
2494
- : 'Sarah sent you a new message'}
2495
- </div>
2496
- </div>
2497
- </div>
2498
- </div>
2499
- ))
2500
- ) : (
2501
- <div
2502
- style={{
2503
- textAlign: 'center',
2504
- padding: '30px 0',
2505
- opacity: 0.7,
2506
- fontSize: '14px',
2507
- }}
2508
- >
2509
- No new notifications
2510
- </div>
2511
- )}
2512
- </div>
2513
- </AtomixGlass>
2514
- </div>
2515
- );
2516
- case 'profile':
2517
- return (
2518
- <div style={{ padding: '10px 0' }}>
2519
- <AtomixGlass
2520
- displacementScale={42}
2521
- blurAmount={1}
2522
- saturation={165}
2523
- aberrationIntensity={2.0}
2524
- elasticity={0.16}
2525
- cornerRadius={15}
2526
- mode="standard"
2527
- >
2528
- <div
2529
- style={{
2530
- padding: '25px 20px',
2531
- display: 'flex',
2532
- flexDirection: 'column',
2533
- alignItems: 'center',
2534
- }}
2535
- >
2536
- <div
2537
- style={{
2538
- width: '80px',
2539
- height: '80px',
2540
- borderRadius: '50%',
2541
- background: 'rgba(255,255,255,0.2)',
2542
- display: 'flex',
2543
- alignItems: 'center',
2544
- justifyContent: 'center',
2545
- fontSize: '36px',
2546
- marginBottom: '15px',
2547
- }}
2548
- >
2549
- 👤
2550
- </div>
2551
- <h3 style={{ margin: '0 0 5px 0', fontSize: '18px', color: 'white' }}>
2552
- User Name
2553
- </h3>
2554
- <p
2555
- style={{ margin: '0 0 20px 0', fontSize: '14px', opacity: 0.7, color: 'white' }}
2556
- >
2557
- user@example.com
2558
- </p>
2559
- <button
2560
- style={{
2561
- background: 'rgba(255,255,255,0.2)',
2562
- border: 'none',
2563
- borderRadius: '8px',
2564
- padding: '8px 16px',
2565
- color: 'white',
2566
- fontSize: '14px',
2567
- width: '100%',
2568
- marginBottom: '10px',
2569
- }}
2570
- >
2571
- Edit Profile
2572
- </button>
2573
- <button
2574
- style={{
2575
- background: 'rgba(255,255,255,0.1)',
2576
- border: 'none',
2577
- borderRadius: '8px',
2578
- padding: '8px 16px',
2579
- color: 'white',
2580
- fontSize: '14px',
2581
- width: '100%',
2582
- }}
2583
- >
2584
- Settings
2585
- </button>
2586
- </div>
2587
- </AtomixGlass>
2588
- </div>
2589
- );
2590
- default:
2591
- return null;
2592
- }
2593
- };
2594
-
2595
- return (
2596
- <BackgroundWrapper
2597
- backgroundImage={'https://images.pexels.com/photos/16702076/pexels-photo-16702076.jpeg'}
2598
- height="90vh"
2599
- style={{
2600
- maxWidth: '1400px',
2601
- padding: '40px 20px',
2602
- }}
2603
- >
2604
- <div
2605
- style={{
2606
- display: 'flex',
2607
- flexWrap: 'wrap',
2608
- justifyContent: 'center',
2609
- }}
2610
- >
2611
- <div style={{ maxWidth: '300px' }}>
2612
- <h2
2613
- style={{
2614
- margin: '0 0 20px 0',
2615
- fontSize: '28px',
2616
- fontWeight: 500,
2617
- color: '#ffffff',
2618
- textShadow: '0 2px 4px rgba(0,0,0,0.2)',
2619
- }}
2620
- >
2621
- Mobile UI Example
2622
- </h2>
2623
-
2624
- <p
2625
- style={{
2626
- fontSize: '16px',
2627
- maxWidth: '600px',
2628
- margin: '0 auto 30px',
2629
- color: '#ffffff',
2630
- textShadow: '0 1px 2px rgba(0,0,0,0.2)',
2631
- }}
2632
- >
2633
- AtomixGlass components optimized for mobile interfaces with touch-friendly controls
2634
- </p>
2635
- </div>
2636
- {/* Phone frame */}
2637
- <div style={phoneFrameStyle}>
2638
- <div style={phoneScreenStyle}>
2639
- <div style={phoneNotchStyle} />
2640
-
2641
- {/* App content */}
2642
- <div style={appContentStyle}>
2643
- {/* Header */}
2644
- <AtomixGlass
2645
- displacementScale={30}
2646
- blurAmount={1}
2647
- saturation={130}
2648
- aberrationIntensity={1.2}
2649
- elasticity={0.1}
2650
- cornerRadius={0}
2651
- mode="standard"
2652
- >
2653
- <div style={headerStyle}>
2654
- <h2 style={{ margin: 0, fontSize: '18px' }}>
2655
- {activeTab.charAt(0).toUpperCase() + activeTab.slice(1)}
2656
- </h2>
2657
- <div
2658
- style={{
2659
- width: '32px',
2660
- height: '32px',
2661
- borderRadius: '50%',
2662
- background: 'rgba(255,255,255,0.1)',
2663
- display: 'flex',
2664
- alignItems: 'center',
2665
- justifyContent: 'center',
2666
- }}
2667
- >
2668
- 👤
2669
- </div>
2670
- </div>
2671
- </AtomixGlass>
2672
-
2673
- {/* Main content area */}
2674
- <div style={mainContentStyle}>{renderTabContent()}</div>
2675
-
2676
- {/* Bottom navigation */}
2677
- <AtomixGlass
2678
- displacementScale={25}
2679
- blurAmount={1}
2680
- saturation={125}
2681
- aberrationIntensity={1.0}
2682
- elasticity={0.08}
2683
- cornerRadius={0}
2684
- mode="standard"
2685
- style={{ borderRadius: '0' }}
2686
- >
2687
- <div
2688
- style={{
2689
- display: 'flex',
2690
- justifyContent: 'space-around',
2691
- padding: '15px 0',
2692
- }}
2693
- >
2694
- {[
2695
- { id: 'home', icon: '🏠' },
2696
- { id: 'search', icon: '🔍' },
2697
- { id: 'notifications', icon: '🔔', badge: notificationCount },
2698
- { id: 'profile', icon: '👤' },
2699
- ].map(tab => (
2700
- <div
2701
- key={tab.id}
2702
- onClick={() => handleTabChange(tab.id)}
2703
- style={{
2704
- display: 'flex',
2705
- flexDirection: 'column',
2706
- alignItems: 'center',
2707
- opacity: activeTab === tab.id ? 1 : 0.6,
2708
- position: 'relative',
2709
- cursor: 'pointer',
2710
- }}
2711
- >
2712
- <div style={{ fontSize: '20px' }}>{tab.icon}</div>
2713
- {tab.badge && tab.badge > 0 && (
2714
- <div
2715
- style={{
2716
- position: 'absolute',
2717
- top: '-5px',
2718
- right: '-5px',
2719
- background: '#ff3b3080',
2720
- color: 'white',
2721
- borderRadius: '50%',
2722
- width: '18px',
2723
- height: '18px',
2724
- fontSize: '12px',
2725
- display: 'flex',
2726
- alignItems: 'center',
2727
- justifyContent: 'center',
2728
- }}
2729
- >
2730
- {tab.badge}
2731
- </div>
2732
- )}
2733
- </div>
2734
- ))}
2735
- </div>
2736
- </AtomixGlass>
2737
- </div>
2738
- </div>
2739
- </div>
2740
- </div>
2741
- </BackgroundWrapper>
2742
- );
2743
- },
2744
- parameters: {
2745
- docs: {
2746
- description: {
2747
- story:
2748
- 'This example demonstrates how AtomixGlass components can be optimized for mobile interfaces. The design showcases a complete mobile app UI with navigation tabs, responsive layouts, and touch-friendly controls. The glass effect provides a modern and elegant look while maintaining excellent readability and usability on smaller screens.',
2749
- },
2750
- },
2751
- },
2752
- };
2753
-
2754
- // Theme switching example
2755
- export const ThemeSwitching: Story = {
2756
- render: () => {
2757
- // eslint-disable-next-line react-hooks/rules-of-hooks
2758
- const [theme, setTheme] = useState<'light' | 'dark'>('dark');
2759
-
2760
- return (
2761
- <BackgroundWrapper
2762
- backgroundImage={
2763
- theme === 'light'
2764
- ? backgroundImages[6] // Cozy café interior for light theme
2765
- : backgroundImages[7] // Desert landscape for dark theme
2766
- }
2767
- >
2768
- <div
2769
- style={{
2770
- display: 'flex',
2771
- flexDirection: 'column',
2772
- alignItems: 'center',
2773
- justifyContent: 'space-between',
2774
- gap: '20px',
2775
- }}
2776
- >
2777
- <AtomixGlass
2778
- displacementScale={60}
2779
- blurAmount={1}
2780
- saturation={theme === 'light' ? 120 : 160}
2781
- aberrationIntensity={2.2}
2782
- elasticity={0.15}
2783
- cornerRadius={20}
2784
- overLight={theme === 'light'}
2785
- mode="standard"
2786
- style={{ width: '350px' }}
2787
- >
2788
- <div style={{ padding: '25px', textAlign: 'center' }}>
2789
- <h2 style={{ marginTop: 0 }}>{theme === 'light' ? 'Light Theme' : 'Dark Theme'}</h2>
2790
- <p>The glass effect adapts to different background themes.</p>
2791
- <button
2792
- className={`u-mt-4 c-btn c-btn--${theme === 'light' ? 'primary' : 'outline-light'}`}
2793
- onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
2794
- >
2795
- Switch to {theme === 'light' ? 'Dark' : 'Light'} Theme
2796
- </button>
2797
- </div>
2798
- </AtomixGlass>
2799
- </div>
2800
- </BackgroundWrapper>
2801
- );
2802
- },
2803
- };
2804
-
2805
- /**
2806
- * Video Background Example
2807
- * Demonstrates the glass effect over a moving video background
2808
- */
2809
- export const VideoBackground: Story = {
2810
- render: () => {
2811
- // eslint-disable-next-line react-hooks/rules-of-hooks
2812
- const [glassSettings, setGlassSettings] = useState({
2813
- displacementScale: 80,
2814
- blurAmount: 0,
2815
- saturation: 150,
2816
- aberrationIntensity: 0,
2817
- cornerRadius: 24,
2818
- mode: 'standard' as const,
2819
- });
2820
-
2821
- const updateSettings = (property: string, value: any) => {
2822
- setGlassSettings(prev => ({
2823
- ...prev,
2824
- [property]: value,
2825
- }));
2826
- };
2827
-
2828
- return (
2829
- <div style={{ position: 'relative', height: '80vh', width: '90vw', overflow: 'hidden' }}>
2830
- {/* Video Background */}
2831
- <video
2832
- autoPlay
2833
- loop
2834
- muted
2835
- playsInline
2836
- style={{
2837
- position: 'absolute',
2838
- top: 0,
2839
- left: 0,
2840
- width: '100%',
2841
- height: '100%',
2842
- objectFit: 'cover',
2843
- zIndex: -1,
2844
- }}
2845
- >
2846
- <source src={backgrounds.videoBackground} type="video/mp4" />
2847
- </video>
2848
-
2849
- {/* Content over video */}
2850
- <div
2851
- style={{
2852
- display: 'flex',
2853
- alignItems: 'center',
2854
- justifyContent: 'center',
2855
- height: '100%',
2856
- padding: '40px',
2857
- gap: '40px',
2858
- flexWrap: 'wrap',
2859
- }}
2860
- >
2861
- {/* Main Glass Card */}
2862
- <AtomixGlass
2863
- displacementScale={glassSettings.displacementScale}
2864
- blurAmount={glassSettings.blurAmount}
2865
- saturation={glassSettings.saturation}
2866
- aberrationIntensity={glassSettings.aberrationIntensity}
2867
- cornerRadius={glassSettings.cornerRadius}
2868
- mode={glassSettings.mode}
2869
- style={{ width: '400px', maxWidth: '100%' }}
2870
- >
2871
- <div style={{ padding: '32px', textAlign: 'center' }}>
2872
- <h2 style={{ marginTop: 0, fontSize: '28px', fontWeight: 600, marginBottom: '16px' }}>
2873
- Glass Over Video
2874
- </h2>
2875
- <p style={{ fontSize: '16px', lineHeight: 1.6, marginBottom: '24px', opacity: 0.9 }}>
2876
- Experience the stunning glass morphism effect overlaid on dynamic video content. The
2877
- glass element creates a sophisticated focal point while maintaining visual harmony
2878
- with the moving background.
2879
- </p>
2880
- <div
2881
- style={{
2882
- display: 'flex',
2883
- justifyContent: 'center',
2884
- gap: '12px',
2885
- flexWrap: 'wrap',
2886
- }}
2887
- >
2888
- <button className="c-btn c-btn--primary">Get Started</button>
2889
- <button className="c-btn c-btn--outline">Learn More</button>
2890
- </div>
2891
- </div>
2892
- </AtomixGlass>
2893
-
2894
- {/* Side Control Panel */}
2895
- <AtomixGlass
2896
- displacementScale={40}
2897
- blurAmount={0.06}
2898
- saturation={120}
2899
- aberrationIntensity={1.5}
2900
- cornerRadius={16}
2901
- mode="standard"
2902
- style={{ width: '300px', maxWidth: '100%' }}
2903
- >
2904
- <div style={{ padding: '24px' }}>
2905
- <h3 style={{ marginTop: 0, fontSize: '18px', marginBottom: '20px' }}>
2906
- Live Controls
2907
- </h3>
2908
-
2909
- <div style={{ marginBottom: '16px' }}>
2910
- <label style={{ display: 'block', fontSize: '14px', marginBottom: '6px' }}>
2911
- Displacement: {glassSettings.displacementScale}
2912
- </label>
2913
- <input
2914
- type="range"
2915
- min="0"
2916
- max="150"
2917
- value={glassSettings.displacementScale}
2918
- onChange={e => updateSettings('displacementScale', parseInt(e.target.value))}
2919
- style={{ width: '100%', accentColor: '#6366f1' }}
2920
- />
2921
- </div>
2922
-
2923
- <div style={{ marginBottom: '16px' }}>
2924
- <label style={{ display: 'block', fontSize: '14px', marginBottom: '6px' }}>
2925
- Blur: {glassSettings.blurAmount}
2926
- </label>
2927
- <input
2928
- type="range"
2929
- min="0"
2930
- max="10"
2931
- step="0.5"
2932
- value={glassSettings.blurAmount}
2933
- onChange={e => updateSettings('blurAmount', parseFloat(e.target.value))}
2934
- style={{ width: '100%', accentColor: '#6366f1' }}
2935
- />
2936
- </div>
2937
-
2938
- <div style={{ marginBottom: '16px' }}>
2939
- <label style={{ display: 'block', fontSize: '14px', marginBottom: '6px' }}>
2940
- Saturation: {glassSettings.saturation}%
2941
- </label>
2942
- <input
2943
- type="range"
2944
- min="50"
2945
- max="300"
2946
- value={glassSettings.saturation}
2947
- onChange={e => updateSettings('saturation', parseInt(e.target.value))}
2948
- style={{ width: '100%', accentColor: '#6366f1' }}
2949
- />
2950
- </div>
2951
-
2952
- <div style={{ marginBottom: '16px' }}>
2953
- <label style={{ display: 'block', fontSize: '14px', marginBottom: '6px' }}>
2954
- Aberration: {glassSettings.aberrationIntensity}
2955
- </label>
2956
- <input
2957
- type="range"
2958
- min="0"
2959
- max="5"
2960
- step="0.1"
2961
- value={glassSettings.aberrationIntensity}
2962
- onChange={e => updateSettings('aberrationIntensity', parseFloat(e.target.value))}
2963
- style={{ width: '100%', accentColor: '#6366f1' }}
2964
- />
2965
- </div>
2966
-
2967
- <div style={{ marginBottom: '16px' }}>
2968
- <label style={{ display: 'block', fontSize: '14px', marginBottom: '6px' }}>
2969
- Corner Radius: {glassSettings.cornerRadius}px
2970
- </label>
2971
- <input
2972
- type="range"
2973
- min="0"
2974
- max="100"
2975
- value={glassSettings.cornerRadius}
2976
- onChange={e => updateSettings('cornerRadius', parseInt(e.target.value))}
2977
- style={{ width: '100%', accentColor: '#6366f1' }}
2978
- />
2979
- </div>
2980
-
2981
- <button
2982
- className="c-btn c-btn--secondary"
2983
- style={{ width: '100%' }}
2984
- onClick={() => {
2985
- setGlassSettings({
2986
- displacementScale: 80,
2987
- blurAmount: 0.08,
2988
- saturation: 150,
2989
- aberrationIntensity: 2.5,
2990
- cornerRadius: 24,
2991
- mode: 'standard',
2992
- });
2993
- }}
2994
- >
2995
- Reset Defaults
2996
- </button>
2997
- </div>
2998
- </AtomixGlass>
2999
- </div>
3000
- </div>
3001
- );
3002
- },
3003
- parameters: {
3004
- docs: {
3005
- description: {
3006
- story:
3007
- 'This example showcases the AtomixGlass component over a dynamic video background, demonstrating how the glass effect creates stunning visual hierarchy and focus over moving content. Use the live controls to experiment with different settings and see how they affect the glass appearance in real-time.',
3008
- },
3009
- },
3010
- },
3011
- };