@shohojdhara/atomix 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/atomix.css +430 -125
- package/dist/atomix.min.css +4 -4
- package/dist/index.d.ts +188 -42
- package/dist/index.esm.js +2049 -1516
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +3571 -3055
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/themes/boomdevs.css +379 -74
- package/dist/themes/boomdevs.min.css +4 -4
- package/dist/themes/esrar.css +430 -125
- package/dist/themes/esrar.min.css +4 -4
- package/dist/themes/mashroom.css +429 -124
- package/dist/themes/mashroom.min.css +4 -4
- package/dist/themes/shaj-default.css +429 -124
- package/dist/themes/shaj-default.min.css +4 -4
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.stories.tsx +684 -21
- package/src/components/Accordion/Accordion.tsx +5 -7
- package/src/components/AtomixGlass/AtomixGlass.stories.tsx +456 -2237
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +2 -2
- package/src/components/AtomixGlass/AtomixGlass.tsx +728 -666
- package/src/components/AtomixGlass/shader-utils.ts +589 -33
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +5800 -0
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +1065 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +1066 -0
- package/src/components/AtomixGlass/stories/ShaderVariants.stories.tsx +397 -0
- package/src/components/AtomixGlass/stories/shared-components.tsx +310 -0
- package/src/components/Badge/Badge.stories.tsx +3 -2
- package/src/components/Badge/Badge.tsx +9 -7
- package/src/components/Button/Button.stories.tsx +501 -20
- package/src/components/Button/Button.tsx +4 -5
- package/src/components/Callout/Callout.tsx +27 -9
- package/src/components/Card/Card.stories.tsx +560 -1
- package/src/components/Card/Card.tsx +1 -1
- package/src/components/DatePicker/DatePicker.stories.tsx +697 -9
- package/src/components/EdgePanel/EdgePanel.stories.tsx +476 -3
- package/src/components/EdgePanel/EdgePanel.tsx +86 -13
- package/src/components/Messages/Messages.stories.tsx +113 -0
- package/src/components/Messages/Messages.tsx +51 -9
- package/src/components/Modal/Modal.stories.tsx +6 -4
- package/src/components/Modal/Modal.tsx +2 -3
- package/src/components/Navigation/Nav/Nav.stories.tsx +469 -0
- package/src/components/Navigation/Nav/Nav.tsx +17 -4
- package/src/components/Navigation/Navbar/Navbar.stories.tsx +413 -0
- package/src/components/Navigation/Navbar/Navbar.tsx +66 -28
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +340 -0
- package/src/components/Navigation/SideMenu/SideMenu.tsx +28 -2
- package/src/components/Progress/Progress.tsx +17 -2
- package/src/components/Spinner/Spinner.tsx +17 -2
- package/src/lib/composables/useBarChart.ts +14 -4
- package/src/lib/composables/useChart.ts +223 -370
- package/src/lib/composables/useChartToolbar.ts +11 -20
- package/src/lib/composables/useEdgePanel.ts +81 -35
- package/src/lib/composables/useLineChart.ts +4 -2
- package/src/lib/composables/usePieChart.ts +4 -14
- package/src/lib/constants/components.ts +1 -0
- package/src/lib/types/components.ts +97 -15
- package/src/styles/01-settings/_settings.background.scss +2 -2
- package/src/styles/01-settings/_settings.edge-panel.scss +1 -1
- package/src/styles/02-tools/_tools.utility-api.scss +62 -27
- package/src/styles/06-components/_components.atomix-glass.scss +72 -0
- package/src/styles/06-components/_components.badge.scss +2 -15
- package/src/styles/06-components/_components.callout.scss +10 -5
- package/src/styles/06-components/_components.edge-panel.scss +101 -0
- package/src/styles/06-components/_components.messages.scss +176 -0
- package/src/styles/06-components/_components.modal.scss +13 -3
- package/src/styles/06-components/_components.navbar.scss +12 -1
- package/src/styles/06-components/_components.side-menu.scss +5 -0
- package/src/styles/99-utilities/_index.scss +1 -0
- package/src/styles/99-utilities/_utilities.glass-fixes.scss +1 -0
- package/src/styles/99-utilities/_utilities.opacity.scss +1 -1
- package/src/components/AtomixGlass/AtomixGlassComprehensivePreview.stories.tsx +0 -1369
|
@@ -0,0 +1,1066 @@
|
|
|
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 { Toggle } from '../../Toggle/Toggle';
|
|
16
|
+
import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
17
|
+
import React from 'react';
|
|
18
|
+
import type { RefObject } from 'react';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Storybook meta configuration for AtomixGlass component
|
|
22
|
+
*
|
|
23
|
+
* This defines the component's metadata, documentation, and controls
|
|
24
|
+
* for the Storybook interface.
|
|
25
|
+
*/
|
|
26
|
+
const meta: Meta<typeof AtomixGlass> = {
|
|
27
|
+
title: 'Components/AtomixGlass',
|
|
28
|
+
component: AtomixGlass,
|
|
29
|
+
parameters: {
|
|
30
|
+
layout: 'centered',
|
|
31
|
+
docs: {
|
|
32
|
+
description: {
|
|
33
|
+
component:
|
|
34
|
+
'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.',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
tags: ['autodocs'],
|
|
39
|
+
argTypes: {
|
|
40
|
+
children: {
|
|
41
|
+
control: 'text',
|
|
42
|
+
description: 'Content to display inside the glass effect',
|
|
43
|
+
},
|
|
44
|
+
displacementScale: {
|
|
45
|
+
control: { type: 'range', min: 0, max: 100, step: 1 },
|
|
46
|
+
description: 'Displacement scale for the glass effect (default: 70)',
|
|
47
|
+
table: { defaultValue: { summary: '70' } },
|
|
48
|
+
},
|
|
49
|
+
blurAmount: {
|
|
50
|
+
control: { type: 'range', min: 0, max: 10, step: 0.5 },
|
|
51
|
+
description: 'Blur amount for the backdrop (default: 0.0625)',
|
|
52
|
+
table: { defaultValue: { summary: '0.0625' } },
|
|
53
|
+
},
|
|
54
|
+
saturation: {
|
|
55
|
+
control: { type: 'range', min: 100, max: 300, step: 5 },
|
|
56
|
+
description: 'Saturation percentage for the backdrop (default: 140)',
|
|
57
|
+
table: { defaultValue: { summary: '140' } },
|
|
58
|
+
},
|
|
59
|
+
aberrationIntensity: {
|
|
60
|
+
control: { type: 'range', min: 0, max: 10, step: 0.1 },
|
|
61
|
+
description: 'Chromatic aberration intensity (default: 2)',
|
|
62
|
+
table: { defaultValue: { summary: '2' } },
|
|
63
|
+
},
|
|
64
|
+
elasticity: {
|
|
65
|
+
control: { type: 'range', min: 0, max: 1, step: 0.01 },
|
|
66
|
+
description: 'Elasticity factor for mouse interactions (default: 0.15)',
|
|
67
|
+
table: { defaultValue: { summary: '0.15' } },
|
|
68
|
+
},
|
|
69
|
+
cornerRadius: {
|
|
70
|
+
control: { type: 'range', min: 0, max: 50, step: 1 },
|
|
71
|
+
description: 'Corner radius in pixels (default: 20)',
|
|
72
|
+
table: { defaultValue: { summary: '20' } },
|
|
73
|
+
},
|
|
74
|
+
globalMousePosition: {
|
|
75
|
+
control: 'object',
|
|
76
|
+
description: 'External global mouse position { x: number; y: number }',
|
|
77
|
+
},
|
|
78
|
+
mouseOffset: {
|
|
79
|
+
control: 'object',
|
|
80
|
+
description: 'External mouse offset { x: number; y: number }',
|
|
81
|
+
},
|
|
82
|
+
mouseContainer: {
|
|
83
|
+
control: false,
|
|
84
|
+
description: 'React ref object for mouse container element',
|
|
85
|
+
},
|
|
86
|
+
padding: {
|
|
87
|
+
control: 'text',
|
|
88
|
+
description: 'Padding for the glass container (default: "0 0")',
|
|
89
|
+
table: { defaultValue: { summary: '"0 0"' } },
|
|
90
|
+
},
|
|
91
|
+
overLight: {
|
|
92
|
+
control: 'boolean',
|
|
93
|
+
description: 'Whether the glass is over a light background (default: false)',
|
|
94
|
+
table: { defaultValue: { summary: 'false' } },
|
|
95
|
+
},
|
|
96
|
+
mode: {
|
|
97
|
+
control: 'select',
|
|
98
|
+
options: ['standard', 'polar', 'prominent', 'shader'],
|
|
99
|
+
description: 'Glass effect mode (default: "standard")',
|
|
100
|
+
table: { defaultValue: { summary: '"standard"' } },
|
|
101
|
+
},
|
|
102
|
+
onClick: {
|
|
103
|
+
action: 'clicked',
|
|
104
|
+
description: 'Click event handler',
|
|
105
|
+
},
|
|
106
|
+
className: {
|
|
107
|
+
control: 'text',
|
|
108
|
+
description: 'Additional CSS class names',
|
|
109
|
+
},
|
|
110
|
+
style: {
|
|
111
|
+
control: 'object',
|
|
112
|
+
description: 'CSS style object',
|
|
113
|
+
},
|
|
114
|
+
'aria-label': {
|
|
115
|
+
control: 'text',
|
|
116
|
+
description: 'ARIA label for accessibility',
|
|
117
|
+
},
|
|
118
|
+
'aria-describedby': {
|
|
119
|
+
control: 'text',
|
|
120
|
+
description: 'ARIA describedby attribute for accessibility',
|
|
121
|
+
},
|
|
122
|
+
role: {
|
|
123
|
+
control: 'text',
|
|
124
|
+
description: 'ARIA role attribute',
|
|
125
|
+
},
|
|
126
|
+
tabIndex: {
|
|
127
|
+
control: 'number',
|
|
128
|
+
description: 'Tab index for keyboard navigation',
|
|
129
|
+
},
|
|
130
|
+
reducedMotion: {
|
|
131
|
+
control: 'boolean',
|
|
132
|
+
description: 'Override for reduced motion preference (default: false)',
|
|
133
|
+
table: { defaultValue: { summary: 'false' } },
|
|
134
|
+
},
|
|
135
|
+
highContrast: {
|
|
136
|
+
control: 'boolean',
|
|
137
|
+
description: 'Override for high contrast preference (default: false)',
|
|
138
|
+
table: { defaultValue: { summary: 'false' } },
|
|
139
|
+
},
|
|
140
|
+
disableEffects: {
|
|
141
|
+
control: 'boolean',
|
|
142
|
+
description: 'Disable all visual effects (default: false)',
|
|
143
|
+
table: { defaultValue: { summary: 'false' } },
|
|
144
|
+
},
|
|
145
|
+
enablePerformanceMonitoring: {
|
|
146
|
+
control: 'boolean',
|
|
147
|
+
description: 'Enable performance monitoring (default: false)',
|
|
148
|
+
table: { defaultValue: { summary: 'false' } },
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export default meta;
|
|
154
|
+
type Story = StoryObj<typeof AtomixGlass>;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Enhanced BackgroundWrapper Component
|
|
158
|
+
*
|
|
159
|
+
* A utility component used throughout the stories to provide consistent background
|
|
160
|
+
* styling and overlay effects. This wrapper creates a visually appealing container
|
|
161
|
+
* for showcasing the AtomixGlass component in various scenarios.
|
|
162
|
+
*
|
|
163
|
+
* @component BackgroundWrapper
|
|
164
|
+
*/
|
|
165
|
+
interface BackgroundWrapperProps {
|
|
166
|
+
/** Child elements to render inside the wrapper */
|
|
167
|
+
children: React.ReactNode;
|
|
168
|
+
/** Array of background images */
|
|
169
|
+
backgrounds?: string[];
|
|
170
|
+
/** Active background index */
|
|
171
|
+
activeIndex?: number;
|
|
172
|
+
/** Optional overlay flag for quick overlay application */
|
|
173
|
+
overlay?: boolean;
|
|
174
|
+
/** Custom overlay color in CSS format */
|
|
175
|
+
overlayColor?: string;
|
|
176
|
+
/** Overlay opacity (0-1) */
|
|
177
|
+
overlayOpacity?: number;
|
|
178
|
+
/** Container height */
|
|
179
|
+
height?: string;
|
|
180
|
+
/** Container width */
|
|
181
|
+
width?: string;
|
|
182
|
+
/** Container border radius */
|
|
183
|
+
borderRadius?: string;
|
|
184
|
+
/** Container padding */
|
|
185
|
+
padding?: string;
|
|
186
|
+
/** Additional CSS class names */
|
|
187
|
+
className?: string;
|
|
188
|
+
/** Additional inline styles */
|
|
189
|
+
style?: React.CSSProperties;
|
|
190
|
+
/** Enable interactive background movement */
|
|
191
|
+
interactive?: boolean;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Interactive Story Container
|
|
196
|
+
*
|
|
197
|
+
* A container that provides mouse tracking and interactive background effects
|
|
198
|
+
* for enhanced storytelling and demonstration purposes.
|
|
199
|
+
*/
|
|
200
|
+
interface StoryContainerProps {
|
|
201
|
+
children: React.ReactNode;
|
|
202
|
+
style?: React.CSSProperties;
|
|
203
|
+
interactive?: boolean;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Interactive Wrapper Component
|
|
208
|
+
*
|
|
209
|
+
* Provides mouse position tracking and offset calculations for interactive stories
|
|
210
|
+
*/
|
|
211
|
+
interface InteractiveWrapperProps {
|
|
212
|
+
children: (
|
|
213
|
+
mousePos: { x: number; y: number },
|
|
214
|
+
mouseOffset: { x: number; y: number },
|
|
215
|
+
containerRef: RefObject<HTMLDivElement>
|
|
216
|
+
) => React.ReactNode;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* BackgroundWrapper Component Implementation
|
|
221
|
+
*
|
|
222
|
+
* Renders a container with a background image and optional overlay,
|
|
223
|
+
* providing a consistent environment for showcasing the AtomixGlass component.
|
|
224
|
+
*
|
|
225
|
+
* @param props - BackgroundWrapperProps
|
|
226
|
+
* @returns JSX.Element
|
|
227
|
+
*/
|
|
228
|
+
const BackgroundWrapper = ({
|
|
229
|
+
children,
|
|
230
|
+
backgrounds = [],
|
|
231
|
+
activeIndex = 0,
|
|
232
|
+
height = '100vh',
|
|
233
|
+
width = '100vw',
|
|
234
|
+
borderRadius = '0',
|
|
235
|
+
padding = '24px',
|
|
236
|
+
className = '',
|
|
237
|
+
style = {},
|
|
238
|
+
}: BackgroundWrapperProps) => {
|
|
239
|
+
return (
|
|
240
|
+
<div
|
|
241
|
+
className={`atomix-glass-background ${className}`}
|
|
242
|
+
style={{
|
|
243
|
+
width,
|
|
244
|
+
minHeight: height,
|
|
245
|
+
backgroundColor: '#1a1a2e',
|
|
246
|
+
display: 'flex',
|
|
247
|
+
alignItems: 'center',
|
|
248
|
+
justifyContent: 'center',
|
|
249
|
+
borderRadius,
|
|
250
|
+
padding,
|
|
251
|
+
overflow: 'hidden',
|
|
252
|
+
...style,
|
|
253
|
+
}}
|
|
254
|
+
>
|
|
255
|
+
{backgrounds.map((bg, i) => (
|
|
256
|
+
<div
|
|
257
|
+
key={bg}
|
|
258
|
+
style={{
|
|
259
|
+
position: 'absolute',
|
|
260
|
+
inset: 0,
|
|
261
|
+
backgroundImage: `url(${bg})`,
|
|
262
|
+
backgroundSize: 'cover',
|
|
263
|
+
backgroundPosition: 'center',
|
|
264
|
+
opacity: i === activeIndex ? 1 : 0,
|
|
265
|
+
visibility: i === activeIndex ? 'visible' : 'hidden',
|
|
266
|
+
transition: 'opacity 800ms ease-in-out',
|
|
267
|
+
}}
|
|
268
|
+
/>
|
|
269
|
+
))}
|
|
270
|
+
<div
|
|
271
|
+
style={{
|
|
272
|
+
position: 'relative',
|
|
273
|
+
width: '100%',
|
|
274
|
+
height: '100%',
|
|
275
|
+
display: 'flex',
|
|
276
|
+
alignItems: 'center',
|
|
277
|
+
justifyContent: 'center',
|
|
278
|
+
color: 'white',
|
|
279
|
+
}}
|
|
280
|
+
>
|
|
281
|
+
{children}
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
);
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Playground - Enhanced playground with presets and code export
|
|
289
|
+
*
|
|
290
|
+
* Professional-grade interactive configuration tool with preset management,
|
|
291
|
+
* code generation, and performance monitoring.
|
|
292
|
+
*/
|
|
293
|
+
export const Playground: Story = {
|
|
294
|
+
render: () => {
|
|
295
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
296
|
+
const [settings, setSettings] = useState({
|
|
297
|
+
displacementScale: 40,
|
|
298
|
+
blurAmount: 1,
|
|
299
|
+
saturation: 140,
|
|
300
|
+
aberrationIntensity: 2,
|
|
301
|
+
elasticity: 0.15,
|
|
302
|
+
cornerRadius: 20,
|
|
303
|
+
overLight: false,
|
|
304
|
+
reducedMotion: false,
|
|
305
|
+
highContrast: false,
|
|
306
|
+
disableEffects: false,
|
|
307
|
+
enableLiquidBlur: false,
|
|
308
|
+
enableBorderEffect: true,
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
312
|
+
const [backgroundIndex, setBackgroundIndex] = useState(0);
|
|
313
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
314
|
+
const [selectedMode, setSelectedMode] = useState<'standard' | 'polar' | 'prominent' | 'shader'>(
|
|
315
|
+
'standard'
|
|
316
|
+
);
|
|
317
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
318
|
+
const [selectedShader, setSelectedShader] = useState<'liquidGlass' | 'plasma' | 'waves' | 'noise'>(
|
|
319
|
+
'liquidGlass'
|
|
320
|
+
);
|
|
321
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
322
|
+
const [showCode, setShowCode] = useState(false);
|
|
323
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
324
|
+
const [copiedCode, setCopiedCode] = useState(false);
|
|
325
|
+
|
|
326
|
+
const presets = {
|
|
327
|
+
minimal: {
|
|
328
|
+
name: 'Minimal',
|
|
329
|
+
icon: '🌿',
|
|
330
|
+
settings: {
|
|
331
|
+
displacementScale: 40,
|
|
332
|
+
blurAmount: 0.5,
|
|
333
|
+
saturation: 110,
|
|
334
|
+
aberrationIntensity: 0.5,
|
|
335
|
+
elasticity: 0.05,
|
|
336
|
+
cornerRadius: 12,
|
|
337
|
+
overLight: false,
|
|
338
|
+
reducedMotion: false,
|
|
339
|
+
highContrast: false,
|
|
340
|
+
disableEffects: false,
|
|
341
|
+
enableLiquidBlur: false,
|
|
342
|
+
enableBorderEffect: true,
|
|
343
|
+
},
|
|
344
|
+
mode: 'standard' as const,
|
|
345
|
+
shader: 'liquidGlass' as const,
|
|
346
|
+
},
|
|
347
|
+
standard: {
|
|
348
|
+
name: 'Standard',
|
|
349
|
+
icon: '⚖️',
|
|
350
|
+
settings: {
|
|
351
|
+
displacementScale: 120,
|
|
352
|
+
blurAmount: 1,
|
|
353
|
+
saturation: 140,
|
|
354
|
+
aberrationIntensity: 2,
|
|
355
|
+
elasticity: 0.15,
|
|
356
|
+
cornerRadius: 20,
|
|
357
|
+
overLight: false,
|
|
358
|
+
reducedMotion: false,
|
|
359
|
+
highContrast: false,
|
|
360
|
+
disableEffects: false,
|
|
361
|
+
enableLiquidBlur: false,
|
|
362
|
+
enableBorderEffect: true,
|
|
363
|
+
},
|
|
364
|
+
mode: 'standard' as const,
|
|
365
|
+
shader: 'liquidGlass' as const,
|
|
366
|
+
},
|
|
367
|
+
premium: {
|
|
368
|
+
name: 'Premium',
|
|
369
|
+
icon: '💎',
|
|
370
|
+
settings: {
|
|
371
|
+
displacementScale: 180,
|
|
372
|
+
blurAmount: 1.5,
|
|
373
|
+
saturation: 170,
|
|
374
|
+
aberrationIntensity: 3.5,
|
|
375
|
+
elasticity: 0.25,
|
|
376
|
+
cornerRadius: 28,
|
|
377
|
+
overLight: false,
|
|
378
|
+
reducedMotion: false,
|
|
379
|
+
highContrast: false,
|
|
380
|
+
disableEffects: false,
|
|
381
|
+
enableLiquidBlur: true,
|
|
382
|
+
enableBorderEffect: true,
|
|
383
|
+
},
|
|
384
|
+
mode: 'prominent' as const,
|
|
385
|
+
shader: 'plasma' as const,
|
|
386
|
+
},
|
|
387
|
+
dramatic: {
|
|
388
|
+
name: 'Dramatic',
|
|
389
|
+
icon: '🎭',
|
|
390
|
+
settings: {
|
|
391
|
+
displacementScale: 200,
|
|
392
|
+
blurAmount: 1,
|
|
393
|
+
saturation: 200,
|
|
394
|
+
aberrationIntensity: 5,
|
|
395
|
+
elasticity: 0.35,
|
|
396
|
+
cornerRadius: 32,
|
|
397
|
+
overLight: false,
|
|
398
|
+
reducedMotion: false,
|
|
399
|
+
highContrast: false,
|
|
400
|
+
disableEffects: false,
|
|
401
|
+
enableLiquidBlur: true,
|
|
402
|
+
enableBorderEffect: true,
|
|
403
|
+
},
|
|
404
|
+
mode: 'shader' as const,
|
|
405
|
+
shader: 'waves' as const,
|
|
406
|
+
},
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
const applyPreset = (presetKey: keyof typeof presets) => {
|
|
410
|
+
const preset = presets[presetKey];
|
|
411
|
+
setSettings(preset.settings as any);
|
|
412
|
+
setSelectedMode(preset.mode);
|
|
413
|
+
setSelectedShader(preset.shader);
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
const generateCode = () => {
|
|
417
|
+
return `<AtomixGlass
|
|
418
|
+
displacementScale={${settings.displacementScale}}
|
|
419
|
+
blurAmount={${settings.blurAmount}}
|
|
420
|
+
saturation={${settings.saturation}}
|
|
421
|
+
aberrationIntensity={${settings.aberrationIntensity}}
|
|
422
|
+
elasticity={${settings.elasticity}}
|
|
423
|
+
cornerRadius={${settings.cornerRadius}}
|
|
424
|
+
overLight={${settings.overLight}}
|
|
425
|
+
mode="${selectedMode}"
|
|
426
|
+
shaderVariant="${selectedShader}"
|
|
427
|
+
reducedMotion={${settings.reducedMotion}}
|
|
428
|
+
highContrast={${settings.highContrast}}
|
|
429
|
+
disableEffects={${settings.disableEffects}}
|
|
430
|
+
enableLiquidBlur={${settings.enableLiquidBlur}}
|
|
431
|
+
enableBorderEffect={${settings.enableBorderEffect}}
|
|
432
|
+
>
|
|
433
|
+
<div className="your-content">
|
|
434
|
+
{/* Your content here */}
|
|
435
|
+
</div>
|
|
436
|
+
</AtomixGlass>`;
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
const copyCode = () => {
|
|
440
|
+
navigator.clipboard.writeText(generateCode());
|
|
441
|
+
setCopiedCode(true);
|
|
442
|
+
setTimeout(() => setCopiedCode(false), 2000);
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
const exportConfig = () => {
|
|
446
|
+
const config = { ...settings, mode: selectedMode, shaderVariant: selectedShader };
|
|
447
|
+
const dataStr = JSON.stringify(config, null, 2);
|
|
448
|
+
const dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);
|
|
449
|
+
const exportFileDefaultName = 'atomix-glass-config.json';
|
|
450
|
+
|
|
451
|
+
const linkElement = document.createElement('a');
|
|
452
|
+
linkElement.setAttribute('href', dataUri);
|
|
453
|
+
linkElement.setAttribute('download', exportFileDefaultName);
|
|
454
|
+
linkElement.click();
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
// Calculate performance score
|
|
458
|
+
const performanceScore = Math.max(
|
|
459
|
+
0,
|
|
460
|
+
Math.min(
|
|
461
|
+
100,
|
|
462
|
+
100 -
|
|
463
|
+
settings.displacementScale * 0.15 -
|
|
464
|
+
Math.abs(settings.blurAmount) * 2 -
|
|
465
|
+
settings.aberrationIntensity * 3 -
|
|
466
|
+
settings.elasticity * 20
|
|
467
|
+
)
|
|
468
|
+
);
|
|
469
|
+
|
|
470
|
+
const getPerformanceColor = () => {
|
|
471
|
+
if (performanceScore >= 80) return '#10B981';
|
|
472
|
+
if (performanceScore >= 60) return '#F59E0B';
|
|
473
|
+
return '#EF4444';
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
const getPerformanceLabel = () => {
|
|
477
|
+
if (performanceScore >= 80) return 'Excellent';
|
|
478
|
+
if (performanceScore >= 60) return 'Good';
|
|
479
|
+
if (performanceScore >= 40) return 'Fair';
|
|
480
|
+
return 'Heavy';
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
const backgrounds = [
|
|
484
|
+
'https://images.unsplash.com/photo-1651483554034-8defec113cf2?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2074',
|
|
485
|
+
'https://images.unsplash.com/photo-1734760858517-ff3e30c4a420?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=987',
|
|
486
|
+
'https://images.unsplash.com/photo-1590634875052-89c137f8df21?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2072',
|
|
487
|
+
'https://images.unsplash.com/photo-1592880476174-2932b3061c30?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2070',
|
|
488
|
+
'https://images.unsplash.com/photo-1591241902480-6cf22542003c?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2070',
|
|
489
|
+
'https://images.unsplash.com/photo-1419242902214-272b3f66ee7a?auto=format&fit=crop&q=80&w=2013',
|
|
490
|
+
'https://images.unsplash.com/photo-1706983677486-3ac9ecbad2e5?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=3132',
|
|
491
|
+
'https://images.unsplash.com/photo-1591322874022-2f5daab8d3d5?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2070',
|
|
492
|
+
'https://images.unsplash.com/photo-1709653600438-08b8088fe0c3?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2670',
|
|
493
|
+
'https://images.unsplash.com/photo-1670758144077-b655e19c75e9?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1974',
|
|
494
|
+
'https://images.unsplash.com/photo-1719583225873-ea5993eb4fcd?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2070',
|
|
495
|
+
'https://images.unsplash.com/photo-1639135650365-516c5bdb40fc?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2073',
|
|
496
|
+
'https://images.unsplash.com/photo-1760592150404-adacb88548e2?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1035',
|
|
497
|
+
'https://images.unsplash.com/photo-1638403338703-672ec4b3c19e?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=1974',
|
|
498
|
+
'https://images.unsplash.com/photo-1639680774410-ced42af91b80?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=987',
|
|
499
|
+
'https://images.unsplash.com/photo-1636757577341-5c135250786d?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=987',
|
|
500
|
+
'https://images.unsplash.com/photo-1653443688877-ff1d74f1e4a0?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=987',
|
|
501
|
+
'https://images.unsplash.com/photo-1495164678535-ecbd76d9fa7d?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2669',
|
|
502
|
+
'https://images.unsplash.com/photo-1742502575383-b908da0fb3ba?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2673',
|
|
503
|
+
'https://images.unsplash.com/photo-1627057075078-26c7caf11dc2?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=2674'
|
|
504
|
+
];
|
|
505
|
+
|
|
506
|
+
return (
|
|
507
|
+
<BackgroundWrapper backgrounds={backgrounds} activeIndex={backgroundIndex}>
|
|
508
|
+
<div className="o-container">
|
|
509
|
+
<div className="o-grid">
|
|
510
|
+
<div className="o-grid__col o-grid__col--4">
|
|
511
|
+
{/* Control Panel */}
|
|
512
|
+
|
|
513
|
+
<AtomixGlass blurAmount={10} elasticity={0} displacementScale={20} padding='20px'>
|
|
514
|
+
<div
|
|
515
|
+
style={{
|
|
516
|
+
height: '90vh',
|
|
517
|
+
overflowY: 'auto',
|
|
518
|
+
borderRight: '1px solid rgba(255,255,255,0.1)',
|
|
519
|
+
padding: '20px',
|
|
520
|
+
}}
|
|
521
|
+
>
|
|
522
|
+
<div className="u-mb-8">
|
|
523
|
+
<h2 className="u-mb-2 u-text-white u-fw-bold" style={{ fontSize: '2rem' }}>
|
|
524
|
+
Advanced Playground
|
|
525
|
+
</h2>
|
|
526
|
+
<p className="u-text-white u-opacity-70 u-fs-sm">
|
|
527
|
+
Fine-tune every parameter with live preview
|
|
528
|
+
</p>
|
|
529
|
+
</div>
|
|
530
|
+
|
|
531
|
+
{/* Performance Indicator */}
|
|
532
|
+
<div
|
|
533
|
+
className="u-mb-6 u-p-4 u-rounded"
|
|
534
|
+
style={{
|
|
535
|
+
background: 'rgba(255,255,255,0.05)',
|
|
536
|
+
border: `2px solid ${getPerformanceColor()}`,
|
|
537
|
+
}}
|
|
538
|
+
>
|
|
539
|
+
<div className="u-d-flex u-justify-content-between u-align-items-center u-mb-2">
|
|
540
|
+
<span className="u-text-white u-fw-semibold">Performance Score</span>
|
|
541
|
+
<span className="u-fw-bold" style={{ color: getPerformanceColor() }}>
|
|
542
|
+
{Math.round(performanceScore)}/100
|
|
543
|
+
</span>
|
|
544
|
+
</div>
|
|
545
|
+
<div
|
|
546
|
+
style={{
|
|
547
|
+
height: '8px',
|
|
548
|
+
background: 'rgba(255,255,255,0.1)',
|
|
549
|
+
borderRadius: '4px',
|
|
550
|
+
overflow: 'hidden',
|
|
551
|
+
}}
|
|
552
|
+
>
|
|
553
|
+
<div
|
|
554
|
+
style={{
|
|
555
|
+
height: '100%',
|
|
556
|
+
width: `${performanceScore}%`,
|
|
557
|
+
background: getPerformanceColor(),
|
|
558
|
+
transition: 'all 0.3s',
|
|
559
|
+
}}
|
|
560
|
+
/>
|
|
561
|
+
</div>
|
|
562
|
+
<div
|
|
563
|
+
className="u-mt-2 u-text-center u-fs-xs"
|
|
564
|
+
style={{ color: getPerformanceColor() }}
|
|
565
|
+
>
|
|
566
|
+
{getPerformanceLabel()} -{' '}
|
|
567
|
+
{performanceScore >= 80
|
|
568
|
+
? 'Suitable for all devices'
|
|
569
|
+
: performanceScore >= 60
|
|
570
|
+
? 'Good for modern devices'
|
|
571
|
+
: 'Best for high-end hardware'}
|
|
572
|
+
</div>
|
|
573
|
+
</div>
|
|
574
|
+
|
|
575
|
+
{/* Quick Presets */}
|
|
576
|
+
<div className="u-mb-6">
|
|
577
|
+
<label className="u-d-block u-mb-3 u-text-white u-fw-semibold">
|
|
578
|
+
Quick Presets
|
|
579
|
+
</label>
|
|
580
|
+
<div
|
|
581
|
+
style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '0.75rem' }}
|
|
582
|
+
>
|
|
583
|
+
{Object.entries(presets).map(([key, preset]) => (
|
|
584
|
+
<button
|
|
585
|
+
key={key}
|
|
586
|
+
onClick={() => applyPreset(key as keyof typeof presets)}
|
|
587
|
+
style={{
|
|
588
|
+
padding: '12px',
|
|
589
|
+
background: 'rgba(255,255,255,0.1)',
|
|
590
|
+
border: '1px solid rgba(255,255,255,0.2)',
|
|
591
|
+
borderRadius: '12px',
|
|
592
|
+
color: 'white',
|
|
593
|
+
cursor: 'pointer',
|
|
594
|
+
transition: 'all 0.2s',
|
|
595
|
+
textAlign: 'center',
|
|
596
|
+
}}
|
|
597
|
+
onMouseEnter={e => {
|
|
598
|
+
e.currentTarget.style.background = 'rgba(255,255,255,0.15)';
|
|
599
|
+
e.currentTarget.style.borderColor = 'rgba(255,255,255,0.3)';
|
|
600
|
+
}}
|
|
601
|
+
onMouseLeave={e => {
|
|
602
|
+
e.currentTarget.style.background = 'rgba(255,255,255,0.1)';
|
|
603
|
+
e.currentTarget.style.borderColor = 'rgba(255,255,255,0.2)';
|
|
604
|
+
}}
|
|
605
|
+
>
|
|
606
|
+
<div style={{ fontSize: '1.5rem', marginBottom: '4px' }}>
|
|
607
|
+
{preset.icon}
|
|
608
|
+
</div>
|
|
609
|
+
<div style={{ fontSize: '0.875rem', fontWeight: 600 }}>{preset.name}</div>
|
|
610
|
+
</button>
|
|
611
|
+
))}
|
|
612
|
+
</div>
|
|
613
|
+
</div>
|
|
614
|
+
|
|
615
|
+
{/* Controls */}
|
|
616
|
+
{Object.entries(settings).map(([key, value]) => (
|
|
617
|
+
<div key={key} className="u-mb-5">
|
|
618
|
+
<div className="u-d-flex u-justify-content-between u-align-items-center u-mb-2">
|
|
619
|
+
<label
|
|
620
|
+
className="u-text-white u-fs-sm u-fw-medium"
|
|
621
|
+
style={{ textTransform: 'capitalize' }}
|
|
622
|
+
>
|
|
623
|
+
{key.replace(/([A-Z])/g, ' $1').trim()}
|
|
624
|
+
</label>
|
|
625
|
+
<span className="u-text-white u-opacity-80 u-fs-sm u-fw-semibold">
|
|
626
|
+
{typeof value === 'boolean'
|
|
627
|
+
? value
|
|
628
|
+
? 'On'
|
|
629
|
+
: 'Off'
|
|
630
|
+
: typeof value === 'number'
|
|
631
|
+
? value.toFixed(
|
|
632
|
+
key.includes('Amount') ||
|
|
633
|
+
key.includes('elasticity') ||
|
|
634
|
+
key.includes('aberration')
|
|
635
|
+
? 2
|
|
636
|
+
: 0
|
|
637
|
+
)
|
|
638
|
+
: value}
|
|
639
|
+
</span>
|
|
640
|
+
</div>
|
|
641
|
+
{typeof value === 'boolean' ? (
|
|
642
|
+
<Toggle
|
|
643
|
+
initialOn={value}
|
|
644
|
+
onToggleOn={() => setSettings(prev => ({ ...prev, [key]: true }))}
|
|
645
|
+
onToggleOff={() => setSettings(prev => ({ ...prev, [key]: false }))}
|
|
646
|
+
/>
|
|
647
|
+
) : (
|
|
648
|
+
<input
|
|
649
|
+
type="range"
|
|
650
|
+
min={0}
|
|
651
|
+
max={
|
|
652
|
+
key === 'displacementScale'
|
|
653
|
+
? 200
|
|
654
|
+
: key === 'saturation'
|
|
655
|
+
? 300
|
|
656
|
+
: key === 'aberrationIntensity'
|
|
657
|
+
? 10
|
|
658
|
+
: key === 'cornerRadius'
|
|
659
|
+
? 100
|
|
660
|
+
: key === 'blurAmount'
|
|
661
|
+
? 10
|
|
662
|
+
: 1
|
|
663
|
+
}
|
|
664
|
+
step={
|
|
665
|
+
key === 'aberrationIntensity' ||
|
|
666
|
+
key === 'elasticity' ||
|
|
667
|
+
key === 'blurAmount'
|
|
668
|
+
? 0.01
|
|
669
|
+
: 1
|
|
670
|
+
}
|
|
671
|
+
value={value as number}
|
|
672
|
+
onChange={e =>
|
|
673
|
+
setSettings(prev => ({ ...prev, [key]: parseFloat(e.target.value) }))
|
|
674
|
+
}
|
|
675
|
+
style={{ width: '100%', height: '6px', accentColor: '#7AFFD7' }}
|
|
676
|
+
/>
|
|
677
|
+
)}
|
|
678
|
+
</div>
|
|
679
|
+
))}
|
|
680
|
+
|
|
681
|
+
{/* Mode Selector */}
|
|
682
|
+
<div className="u-mb-5">
|
|
683
|
+
<label className="u-d-block u-mb-2 u-text-white u-fw-semibold">
|
|
684
|
+
Glass Mode
|
|
685
|
+
</label>
|
|
686
|
+
<select
|
|
687
|
+
value={selectedMode}
|
|
688
|
+
onChange={e => setSelectedMode(e.target.value as any)}
|
|
689
|
+
style={{
|
|
690
|
+
width: '100%',
|
|
691
|
+
padding: '12px',
|
|
692
|
+
background: 'rgba(255,255,255,0.1)',
|
|
693
|
+
border: '1px solid rgba(255,255,255,0.2)',
|
|
694
|
+
borderRadius: '8px',
|
|
695
|
+
color: 'white',
|
|
696
|
+
fontSize: '1rem',
|
|
697
|
+
}}
|
|
698
|
+
>
|
|
699
|
+
<option value="standard" style={{ background: '#1a1a1a' }}>
|
|
700
|
+
Standard
|
|
701
|
+
</option>
|
|
702
|
+
<option value="polar" style={{ background: '#1a1a1a' }}>
|
|
703
|
+
Polar
|
|
704
|
+
</option>
|
|
705
|
+
<option value="prominent" style={{ background: '#1a1a1a' }}>
|
|
706
|
+
Prominent
|
|
707
|
+
</option>
|
|
708
|
+
<option value="shader" style={{ background: '#1a1a1a' }}>
|
|
709
|
+
Shader
|
|
710
|
+
</option>
|
|
711
|
+
</select>
|
|
712
|
+
</div>
|
|
713
|
+
|
|
714
|
+
{/* Shader Variant Selector */}
|
|
715
|
+
{selectedMode === 'shader' && (
|
|
716
|
+
<div className="u-mb-5">
|
|
717
|
+
<label className="u-d-block u-mb-2 u-text-white u-fw-semibold">
|
|
718
|
+
Shader Variant
|
|
719
|
+
</label>
|
|
720
|
+
<select
|
|
721
|
+
value={selectedShader}
|
|
722
|
+
onChange={e => setSelectedShader(e.target.value as any)}
|
|
723
|
+
style={{
|
|
724
|
+
width: '100%',
|
|
725
|
+
padding: '12px',
|
|
726
|
+
background: 'rgba(255,255,255,0.1)',
|
|
727
|
+
border: '1px solid rgba(255,255,255,0.2)',
|
|
728
|
+
borderRadius: '8px',
|
|
729
|
+
color: 'white',
|
|
730
|
+
fontSize: '1rem',
|
|
731
|
+
}}
|
|
732
|
+
>
|
|
733
|
+
<option value="liquidGlass" style={{ background: '#1a1a1a' }}>
|
|
734
|
+
Liquid Glass
|
|
735
|
+
</option>
|
|
736
|
+
<option value="plasma" style={{ background: '#1a1a1a' }}>
|
|
737
|
+
Plasma
|
|
738
|
+
</option>
|
|
739
|
+
<option value="waves" style={{ background: '#1a1a1a' }}>
|
|
740
|
+
Waves
|
|
741
|
+
</option>
|
|
742
|
+
<option value="noise" style={{ background: '#1a1a1a' }}>
|
|
743
|
+
Noise
|
|
744
|
+
</option>
|
|
745
|
+
</select>
|
|
746
|
+
</div>
|
|
747
|
+
)}
|
|
748
|
+
|
|
749
|
+
{/* Background Control */}
|
|
750
|
+
<div className="u-mb-6">
|
|
751
|
+
<label className="u-d-block u-mb-2 u-text-white u-fw-semibold">
|
|
752
|
+
Background Image
|
|
753
|
+
</label>
|
|
754
|
+
<input
|
|
755
|
+
type="range"
|
|
756
|
+
min={0}
|
|
757
|
+
max={backgrounds.length}
|
|
758
|
+
step={1}
|
|
759
|
+
value={backgroundIndex}
|
|
760
|
+
onChange={e => setBackgroundIndex(parseInt(e.target.value))}
|
|
761
|
+
style={{ width: '100%', height: '6px', accentColor: '#7AFFD7' }}
|
|
762
|
+
/>
|
|
763
|
+
<div className="u-mt-2 u-text-center u-text-white u-opacity-70 u-fs-xs">
|
|
764
|
+
Background {backgroundIndex + 1} of {backgrounds.length}
|
|
765
|
+
</div>
|
|
766
|
+
</div>
|
|
767
|
+
|
|
768
|
+
{/* Action Buttons */}
|
|
769
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
|
|
770
|
+
<Button
|
|
771
|
+
variant="primary"
|
|
772
|
+
size="md"
|
|
773
|
+
onClick={() => setShowCode(!showCode)}
|
|
774
|
+
style={{ width: '100%' }}
|
|
775
|
+
>
|
|
776
|
+
{showCode ? '👁️ Hide Code' : '💻 Show Code'}
|
|
777
|
+
</Button>
|
|
778
|
+
<Button
|
|
779
|
+
variant="outline-light"
|
|
780
|
+
size="md"
|
|
781
|
+
onClick={copyCode}
|
|
782
|
+
style={{ width: '100%' }}
|
|
783
|
+
>
|
|
784
|
+
{copiedCode ? '✓ Copied!' : '📋 Copy Code'}
|
|
785
|
+
</Button>
|
|
786
|
+
<Button
|
|
787
|
+
variant="outline-light"
|
|
788
|
+
size="md"
|
|
789
|
+
onClick={exportConfig}
|
|
790
|
+
style={{ width: '100%' }}
|
|
791
|
+
>
|
|
792
|
+
💾 Export Config
|
|
793
|
+
</Button>
|
|
794
|
+
<Button
|
|
795
|
+
variant="ghost"
|
|
796
|
+
size="md"
|
|
797
|
+
onClick={() => {
|
|
798
|
+
setSettings({
|
|
799
|
+
displacementScale: 120,
|
|
800
|
+
blurAmount: 0,
|
|
801
|
+
saturation: 140,
|
|
802
|
+
aberrationIntensity: 2,
|
|
803
|
+
elasticity: 0.15,
|
|
804
|
+
cornerRadius: 20,
|
|
805
|
+
overLight: false,
|
|
806
|
+
reducedMotion: false,
|
|
807
|
+
highContrast: false,
|
|
808
|
+
disableEffects: false,
|
|
809
|
+
enableLiquidBlur: false,
|
|
810
|
+
enableBorderEffect: true,
|
|
811
|
+
});
|
|
812
|
+
setSelectedMode('standard');
|
|
813
|
+
setSelectedShader('liquidGlass');
|
|
814
|
+
}}
|
|
815
|
+
style={{ width: '100%' }}
|
|
816
|
+
>
|
|
817
|
+
🔄 Reset
|
|
818
|
+
</Button>
|
|
819
|
+
</div>
|
|
820
|
+
</div>
|
|
821
|
+
</AtomixGlass>
|
|
822
|
+
</div>
|
|
823
|
+
{/* Preview Area */}
|
|
824
|
+
<div className="o-grid__col o-grid__col--8">
|
|
825
|
+
<div
|
|
826
|
+
style={{
|
|
827
|
+
display: 'flex',
|
|
828
|
+
alignItems: 'center',
|
|
829
|
+
justifyContent: 'center',
|
|
830
|
+
padding: '3rem'
|
|
831
|
+
}}
|
|
832
|
+
>
|
|
833
|
+
{showCode ? (
|
|
834
|
+
<div style={{ width: '100%' }}>
|
|
835
|
+
<AtomixGlass
|
|
836
|
+
displacementScale={80}
|
|
837
|
+
aberrationIntensity={1}
|
|
838
|
+
cornerRadius={16}
|
|
839
|
+
saturation={120}
|
|
840
|
+
>
|
|
841
|
+
<div style={{ padding: '2rem' }}>
|
|
842
|
+
<div className="u-d-flex u-justify-content-between u-align-items-center u-mb-4">
|
|
843
|
+
<h3 className="u-text-white u-fw-semibold" style={{ fontSize: '1.5rem' }}>
|
|
844
|
+
Generated Code
|
|
845
|
+
</h3>
|
|
846
|
+
<Button variant="primary" size="sm" onClick={copyCode}>
|
|
847
|
+
{copiedCode ? '✓ Copied' : 'Copy'}
|
|
848
|
+
</Button>
|
|
849
|
+
</div>
|
|
850
|
+
<pre
|
|
851
|
+
style={{
|
|
852
|
+
background: 'rgba(0,0,0,0.5)',
|
|
853
|
+
padding: '1.5rem',
|
|
854
|
+
borderRadius: '8px',
|
|
855
|
+
overflow: 'auto',
|
|
856
|
+
maxHeight: '500px',
|
|
857
|
+
color: '#7AFFD7',
|
|
858
|
+
fontSize: '0.875rem',
|
|
859
|
+
lineHeight: 1.6,
|
|
860
|
+
}}
|
|
861
|
+
>
|
|
862
|
+
<code>{generateCode()}</code>
|
|
863
|
+
</pre>
|
|
864
|
+
</div>
|
|
865
|
+
</AtomixGlass>
|
|
866
|
+
</div>
|
|
867
|
+
) : (
|
|
868
|
+
<AtomixGlass
|
|
869
|
+
displacementScale={settings.displacementScale}
|
|
870
|
+
blurAmount={settings.blurAmount}
|
|
871
|
+
saturation={settings.saturation}
|
|
872
|
+
aberrationIntensity={settings.aberrationIntensity}
|
|
873
|
+
elasticity={settings.elasticity}
|
|
874
|
+
cornerRadius={settings.cornerRadius}
|
|
875
|
+
overLight={settings.overLight}
|
|
876
|
+
mode={selectedMode}
|
|
877
|
+
shaderVariant={selectedShader as any}
|
|
878
|
+
reducedMotion={settings.reducedMotion}
|
|
879
|
+
highContrast={settings.highContrast}
|
|
880
|
+
disableEffects={settings.disableEffects}
|
|
881
|
+
enableLiquidBlur={settings.enableLiquidBlur}
|
|
882
|
+
enableBorderEffect={settings.enableBorderEffect}
|
|
883
|
+
style={{ width: '100%' }}
|
|
884
|
+
>
|
|
885
|
+
<div style={{ padding: '2rem', textAlign: 'center' }}>
|
|
886
|
+
<div
|
|
887
|
+
style={{
|
|
888
|
+
display: 'inline-flex',
|
|
889
|
+
alignItems: 'center',
|
|
890
|
+
padding: '8px 20px',
|
|
891
|
+
borderRadius: '24px',
|
|
892
|
+
background: 'rgba(122, 255, 215, 0.2)',
|
|
893
|
+
color: '#7AFFD7',
|
|
894
|
+
fontSize: '0.875rem',
|
|
895
|
+
fontWeight: 600,
|
|
896
|
+
marginBottom: '1.5rem',
|
|
897
|
+
}}
|
|
898
|
+
>
|
|
899
|
+
✨ LIVE PREVIEW
|
|
900
|
+
</div>
|
|
901
|
+
<h2 className="u-mb-4 u-text-white u-fw-bold" style={{ fontSize: '2.5rem' }}>
|
|
902
|
+
AtomixGlass
|
|
903
|
+
</h2>
|
|
904
|
+
<p
|
|
905
|
+
className="u-mb-6 u-opacity-90"
|
|
906
|
+
style={{ fontSize: '1.125rem', lineHeight: 1.6 }}
|
|
907
|
+
>
|
|
908
|
+
Adjust the controls on the left to see real-time changes. Each parameter
|
|
909
|
+
affects the visual appearance and performance characteristics of the glass
|
|
910
|
+
effect.
|
|
911
|
+
</p>
|
|
912
|
+
<div
|
|
913
|
+
className="u-d-flex u-justify-content-center u-flex-wrap"
|
|
914
|
+
style={{ gap: '1rem' }}
|
|
915
|
+
>
|
|
916
|
+
<Button variant="primary" size="lg">
|
|
917
|
+
Primary Action
|
|
918
|
+
</Button>
|
|
919
|
+
<Button variant="outline-light" size="lg">
|
|
920
|
+
Secondary
|
|
921
|
+
</Button>
|
|
922
|
+
</div>
|
|
923
|
+
{/* Dynamic Info Panel */}
|
|
924
|
+
<div className="u-mt-8" style={{ display: 'grid', gap: '1rem' }}>
|
|
925
|
+
{/* Current Configuration */}
|
|
926
|
+
<div
|
|
927
|
+
className="u-p-4 u-rounded"
|
|
928
|
+
style={{ background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.15)' }}
|
|
929
|
+
>
|
|
930
|
+
<div className="u-mb-3 u-fw-semibold u-fs-sm" style={{ color: '#7AFFD7' }}>
|
|
931
|
+
📊 Current Configuration
|
|
932
|
+
</div>
|
|
933
|
+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr 1fr 1fr', gap: '0.75rem' }}>
|
|
934
|
+
<div>
|
|
935
|
+
<div className="u-fs-xs u-opacity-70">Mode</div>
|
|
936
|
+
<div className="u-fw-semibold" style={{ textTransform: 'capitalize' }}>{selectedMode}</div>
|
|
937
|
+
</div>
|
|
938
|
+
<div>
|
|
939
|
+
<div className="u-fs-xs u-opacity-70">Shader</div>
|
|
940
|
+
<div className="u-fw-semibold" style={{ textTransform: 'capitalize' }}>{selectedShader}</div>
|
|
941
|
+
</div>
|
|
942
|
+
<div>
|
|
943
|
+
<div className="u-fs-xs u-opacity-70">Displacement</div>
|
|
944
|
+
<div className="u-fw-semibold">{settings.displacementScale}px</div>
|
|
945
|
+
</div>
|
|
946
|
+
<div>
|
|
947
|
+
<div className="u-fs-xs u-opacity-70">Aberration</div>
|
|
948
|
+
<div className="u-fw-semibold">{settings.aberrationIntensity.toFixed(1)}</div>
|
|
949
|
+
</div>
|
|
950
|
+
<div>
|
|
951
|
+
<div className="u-fs-xs u-opacity-70">Blur</div>
|
|
952
|
+
<div className="u-fw-semibold">{settings.blurAmount.toFixed(2)}</div>
|
|
953
|
+
</div>
|
|
954
|
+
<div>
|
|
955
|
+
<div className="u-fs-xs u-opacity-70">Elasticity</div>
|
|
956
|
+
<div className="u-fw-semibold">{settings.elasticity.toFixed(2)}</div>
|
|
957
|
+
</div>
|
|
958
|
+
</div>
|
|
959
|
+
</div>
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
{/* Visual Characteristics */}
|
|
964
|
+
<div
|
|
965
|
+
className="u-p-4 u-rounded"
|
|
966
|
+
style={{ background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.15)' }}
|
|
967
|
+
>
|
|
968
|
+
<div className="u-mb-3 u-fw-semibold u-fs-sm" style={{ color: '#7AFFD7' }}>
|
|
969
|
+
🎨 Visual Characteristics
|
|
970
|
+
</div>
|
|
971
|
+
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem' }}>
|
|
972
|
+
<div
|
|
973
|
+
style={{
|
|
974
|
+
padding: '4px 12px',
|
|
975
|
+
borderRadius: '12px',
|
|
976
|
+
background: settings.enableLiquidBlur ? 'rgba(122, 255, 215, 0.2)' : 'rgba(255,255,255,0.1)',
|
|
977
|
+
fontSize: '0.75rem',
|
|
978
|
+
border: settings.enableLiquidBlur ? '1px solid #7AFFD7' : '1px solid transparent',
|
|
979
|
+
}}
|
|
980
|
+
>
|
|
981
|
+
{settings.enableLiquidBlur ? '✓' : '○'} Liquid Blur
|
|
982
|
+
</div>
|
|
983
|
+
<div
|
|
984
|
+
style={{
|
|
985
|
+
padding: '4px 12px',
|
|
986
|
+
borderRadius: '12px',
|
|
987
|
+
background: settings.enableBorderEffect ? 'rgba(122, 255, 215, 0.2)' : 'rgba(255,255,255,0.1)',
|
|
988
|
+
fontSize: '0.75rem',
|
|
989
|
+
border: settings.enableBorderEffect ? '1px solid #7AFFD7' : '1px solid transparent',
|
|
990
|
+
}}
|
|
991
|
+
>
|
|
992
|
+
{settings.enableBorderEffect ? '✓' : '○'} Border Effect
|
|
993
|
+
</div>
|
|
994
|
+
<div
|
|
995
|
+
style={{
|
|
996
|
+
padding: '4px 12px',
|
|
997
|
+
borderRadius: '12px',
|
|
998
|
+
background: settings.reducedMotion ? 'rgba(239, 68, 68, 0.2)' : 'rgba(255,255,255,0.1)',
|
|
999
|
+
fontSize: '0.75rem',
|
|
1000
|
+
border: settings.reducedMotion ? '1px solid #EF4444' : '1px solid transparent',
|
|
1001
|
+
}}
|
|
1002
|
+
>
|
|
1003
|
+
{settings.reducedMotion ? '✓' : '○'} Reduced Motion
|
|
1004
|
+
</div>
|
|
1005
|
+
<div
|
|
1006
|
+
style={{
|
|
1007
|
+
padding: '4px 12px',
|
|
1008
|
+
borderRadius: '12px',
|
|
1009
|
+
background: settings.highContrast ? 'rgba(245, 158, 11, 0.2)' : 'rgba(255,255,255,0.1)',
|
|
1010
|
+
fontSize: '0.75rem',
|
|
1011
|
+
border: settings.highContrast ? '1px solid #F59E0B' : '1px solid transparent',
|
|
1012
|
+
}}
|
|
1013
|
+
>
|
|
1014
|
+
{settings.highContrast ? '✓' : '○'} High Contrast
|
|
1015
|
+
</div>
|
|
1016
|
+
</div>
|
|
1017
|
+
</div>
|
|
1018
|
+
|
|
1019
|
+
{/* Quick Stats */}
|
|
1020
|
+
<div
|
|
1021
|
+
className="u-p-4 u-rounded"
|
|
1022
|
+
style={{ background: 'rgba(255,255,255,0.08)', border: '1px solid rgba(255,255,255,0.15)' }}
|
|
1023
|
+
>
|
|
1024
|
+
<div className="u-mb-3 u-fw-semibold u-fs-sm" style={{ color: '#7AFFD7' }}>
|
|
1025
|
+
📈 Quick Stats
|
|
1026
|
+
</div>
|
|
1027
|
+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: '0.75rem', fontSize: '0.875rem' }}>
|
|
1028
|
+
<div>
|
|
1029
|
+
<span className="u-opacity-70">Saturation:</span>
|
|
1030
|
+
<span className="u-fw-semibold u-ml-2">{settings.saturation}%</span>
|
|
1031
|
+
</div>
|
|
1032
|
+
<div>
|
|
1033
|
+
<span className="u-opacity-70">Radius:</span>
|
|
1034
|
+
<span className="u-fw-semibold u-ml-2">{settings.cornerRadius}px</span>
|
|
1035
|
+
</div>
|
|
1036
|
+
<div>
|
|
1037
|
+
<span className="u-opacity-70">Background:</span>
|
|
1038
|
+
<span className="u-fw-semibold u-ml-2">{backgroundIndex + 1}/{backgrounds.length}</span>
|
|
1039
|
+
</div>
|
|
1040
|
+
<div>
|
|
1041
|
+
<span className="u-opacity-70">Effects:</span>
|
|
1042
|
+
<span className="u-fw-semibold u-ml-2">{settings.disableEffects ? 'Disabled' : 'Enabled'}</span>
|
|
1043
|
+
</div>
|
|
1044
|
+
</div>
|
|
1045
|
+
</div>
|
|
1046
|
+
</div>
|
|
1047
|
+
</div>
|
|
1048
|
+
</AtomixGlass>
|
|
1049
|
+
)}
|
|
1050
|
+
</div>
|
|
1051
|
+
</div>
|
|
1052
|
+
</div>
|
|
1053
|
+
</div>
|
|
1054
|
+
</BackgroundWrapper>
|
|
1055
|
+
);
|
|
1056
|
+
},
|
|
1057
|
+
parameters: {
|
|
1058
|
+
docs: {
|
|
1059
|
+
description: {
|
|
1060
|
+
story:
|
|
1061
|
+
'Advanced interactive playground with preset configurations, code generation, configuration export, and real-time performance monitoring. Perfect for fine-tuning AtomixGlass for your specific use case.',
|
|
1062
|
+
},
|
|
1063
|
+
},
|
|
1064
|
+
layout: 'fullscreen',
|
|
1065
|
+
},
|
|
1066
|
+
};
|